예제 #1
0
        /// <summary>
        /// Creates or populates Revit elements based on the information contained in this class.
        /// </summary>
        /// <param name="doc">The document.</param>
        protected override void Create(Document doc)
        {
            // If we created an element above, then we will set the shape of it to be the same of the shapes of the contained spaces.
            IList <GeometryObject> geomObjs = new List <GeometryObject>();

            foreach (IFCObjectDefinition objDef in RelatedObjects)
            {
                if (!(objDef is IFCSpace))
                {
                    continue;
                }

                // This lets us create a copy of the space geometry with the Zone graphics style.
                IList <IFCSolidInfo> solids = IFCElement.CloneElementGeometry(doc, objDef as IFCProduct, this, false);
                if (solids != null)
                {
                    foreach (IFCSolidInfo solidGeom in solids)
                    {
                        geomObjs.Add(solidGeom.GeometryObject);
                    }
                }
            }

            DirectShape zoneElement = IFCElementUtil.CreateElement(doc, CategoryId, GlobalId, geomObjs);

            if (zoneElement != null)
            {
                CreatedElementId = zoneElement.Id;
                CreatedGeometry  = geomObjs;
            }

            base.Create(doc);
        }
        /// <summary>
        /// Creates or populates Revit elements based on the information contained in this class.
        /// </summary>
        /// <param name="doc">The document.</param>
        protected override void Create(Document doc)
        {
            DirectShapeType shapeType = Importer.TheCache.UseElementByGUID <DirectShapeType>(doc, GlobalId);

            if (shapeType == null)
            {
                shapeType = IFCElementUtil.CreateElementType(doc, GetVisibleName(), CategoryId, Id);
            }
            else
            {
                // If we used the element from the cache, we want to make sure that the IFCRepresentationMap can access it
                // instead of creating a new element.
                Importer.TheCache.CreatedDirectShapeTypes[Id] = shapeType.Id;
            }

            if (shapeType == null)
            {
                throw new InvalidOperationException("Couldn't create DirectShapeType for IfcTypeObject.");
            }

            m_CreatedElementId = shapeType.Id;

            base.Create(doc);

            TraverseSubElements(doc);
        }
예제 #3
0
        /// <summary>
        /// Creates or populates Revit elements based on the information contained in this class.
        /// </summary>
        /// <param name="doc">The document.</param>
        protected override void Create(Document doc)
        {
            DirectShapeType shapeType = Importer.TheCache.UseElementByGUID <DirectShapeType>(doc, GlobalId);

            if (shapeType == null)
            {
                shapeType = DirectShapeType.Create(doc, GetName("DirectShapeType"), IFCElementUtil.GetDSValidCategoryId(doc, CategoryId, Id));
            }

            if (shapeType == null)
            {
                throw new InvalidOperationException("Couldn't create DirectShapeType for IfcTypeObject.");
            }

            m_CreatedElementId = shapeType.Id;

            base.Create(doc);

            TraverseSubElements(doc);
        }
예제 #4
0
        /// <summary>
        /// Creates or populates Revit elements based on the information contained in this class.
        /// </summary>
        /// <param name="doc">The document.</param>
        protected virtual void TraverseSubElements(Document doc)
        {
            IList <ElementId> subElementIds = new List <ElementId>();

            if (ComposedObjectDefinitions != null)
            {
                foreach (IFCObjectDefinition objectDefinition in ComposedObjectDefinitions)
                {
                    IFCObjectDefinition.CreateElement(doc, objectDefinition);
                    if (objectDefinition.CreatedElementId != ElementId.InvalidElementId)
                    {
                        subElementIds.Add(objectDefinition.CreatedElementId);
                    }
                }
            }

            if (GroupSubElements())
            {
                if (subElementIds.Count > 0)
                {
                    if (CreatedElementId != ElementId.InvalidElementId)
                    {
                        subElementIds.Add(CreatedElementId);
                    }

                    // We aren't yet actually grouping the elements.  DirectShape doesn't support grouping, and
                    // the Group element doesn't support adding parameters.  For now, we will create a DirectShape that "forgets"
                    // the association, which is good enough for link.
                    DirectShape directShape = IFCElementUtil.CreateElement(doc, CategoryId, Importer.ImportAppGUID(), GlobalId);
                    //Group group = doc.Create.NewGroup(subElementIds);
                    if (directShape != null)
                    {
                        CreatedElementId = directShape.Id;
                    }
                    else
                    {
                        IFCImportFile.TheLog.LogCreationError(this, null, false);
                    }
                }
            }
        }
        /// <summary>
        /// Create geometry for a particular representation map.
        /// </summary>
        /// <param name="shapeEditScope">The geometry creation scope.</param>
        /// <param name="lcs">Local coordinate system for the geometry, without scale.</param>
        /// <param name="scaledLcs">Local coordinate system for the geometry, including scale, potentially non-uniform.</param>
        /// <remarks>For this function, if lcs is null, we will create a library item for the geometry.</remarks>
        public void CreateShape(IFCImportShapeEditScope shapeEditScope, Transform lcs, Transform scaledLcs, string guid)
        {
            bool creatingLibraryDefinition = (lcs == null);

            if (MappedRepresentation != null)
            {
                // Look for cached shape; if found, return.
                if (creatingLibraryDefinition)
                {
                    if (IFCImportFile.TheFile.ShapeLibrary.FindDefinitionType(Id.ToString()) != ElementId.InvalidElementId)
                    {
                        return;
                    }
                }

                Transform mappingTransform = null;
                if (lcs == null)
                {
                    mappingTransform = MappingOrigin;
                }
                else
                {
                    if (MappingOrigin == null)
                    {
                        mappingTransform = lcs;
                    }
                    else
                    {
                        mappingTransform = lcs.Multiply(MappingOrigin);
                    }
                }

                Transform scaledMappingTransform = null;
                if (scaledLcs == null)
                {
                    scaledMappingTransform = mappingTransform;
                }
                else
                {
                    if (MappingOrigin == null)
                    {
                        scaledMappingTransform = scaledLcs;
                    }
                    else
                    {
                        scaledMappingTransform = scaledLcs.Multiply(MappingOrigin);
                    }
                }

                int numExistingSolids = shapeEditScope.Creator.Solids.Count;
                int numExistingCurves = shapeEditScope.Creator.FootprintCurves.Count;

                MappedRepresentation.CreateShape(shapeEditScope, mappingTransform, scaledMappingTransform, guid);

                if (creatingLibraryDefinition)
                {
                    int numNewSolids = shapeEditScope.Creator.Solids.Count;
                    int numNewCurves = shapeEditScope.Creator.FootprintCurves.Count;

                    if ((numExistingSolids != numNewSolids) || (numExistingCurves != numNewCurves))
                    {
                        IList <GeometryObject> mappedSolids = new List <GeometryObject>();
                        for (int ii = numExistingSolids; ii < numNewSolids; ii++)
                        {
                            mappedSolids.Add(shapeEditScope.Creator.Solids[numExistingSolids].GeometryObject);
                            shapeEditScope.Creator.Solids.RemoveAt(numExistingSolids);
                        }

                        IList <Curve> mappedCurves = new List <Curve>();
                        for (int ii = numExistingCurves; ii < numNewCurves; ii++)
                        {
                            mappedCurves.Add(shapeEditScope.Creator.FootprintCurves[numExistingCurves]);
                            shapeEditScope.Creator.FootprintCurves.RemoveAt(numExistingCurves);
                        }
                        shapeEditScope.AddPlanViewCurves(mappedCurves, Id);

                        Document        doc             = IFCImportFile.TheFile.Document;
                        DirectShapeType directShapeType = null;

                        IFCTypeProduct typeProduct = null;
                        if (Importer.TheCache.RepMapToTypeProduct.TryGetValue(Id, out typeProduct))
                        {
                            ElementId directShapeTypeId = ElementId.InvalidElementId;
                            if (Importer.TheCache.CreatedDirectShapeTypes.TryGetValue(typeProduct.Id, out directShapeTypeId))
                            {
                                directShapeType = doc.GetElement(directShapeTypeId) as DirectShapeType;
                            }
                        }

                        if (directShapeType == null)
                        {
                            string directShapeTypeName = Id.ToString();
                            directShapeType = IFCElementUtil.CreateElementType(doc, directShapeTypeName, shapeEditScope.CategoryId, Id);
                        }

                        // Note that this assumes that there is only one 2D rep per DirectShapeType.
                        directShapeType.AppendShape(mappedSolids);
                        if (mappedCurves.Count != 0)
                        {
                            shapeEditScope.SetPlanViewRep(directShapeType);
                        }

                        IFCImportFile.TheFile.ShapeLibrary.AddDefinitionType(Id.ToString(), directShapeType.Id);
                    }
                }
            }
        }
예제 #6
0
        /// <summary>
        /// Creates or populates Revit elements based on the information contained in this class.
        /// </summary>
        /// <param name="doc">The document.</param>
        protected override void Create(Document doc)
        {
            Transform lcs = (ObjectLocation != null) ? ObjectLocation.TotalTransform : Transform.Identity;

            if (ProductRepresentation != null)
            {
                if (ProductRepresentation.IsValid())
                {
                    using (IFCImportShapeEditScope shapeEditScope = IFCImportShapeEditScope.Create(doc, this))
                    {
                        shapeEditScope.GraphicsStyleId = m_GraphicsStyleId;
                        shapeEditScope.CategoryId      = CategoryId;

                        // The name can be added as well. but it is usually less useful than 'oid'
                        string myId = GlobalId; // + "(" + Name + ")";

                        ProductRepresentation.CreateProductRepresentation(shapeEditScope, lcs, lcs, myId);

                        int numSolids = Solids.Count;
                        int numVoids  = Voids.Count;
                        if ((numSolids > 0) && (numVoids > 0))
                        {
                            // We may have some GeometryInstances.  These need to be "exploded" to do the cutting.
                            for (int solidIdx = 0; solidIdx < numSolids; solidIdx++)
                            {
                                if (Solids[solidIdx].GeometryObject is GeometryInstance)
                                {
                                    //// This code currently doesn't work, so commented out.
                                    //GeometryInstance geomInst = Solids[solidIdx].GeometryObject as GeometryInstance;
                                    //GeometryElement geomElem = geomInst.GetInstanceGeometry();

                                    //foreach (GeometryObject geomObj in geomElem)
                                    //{
                                    //if (geomObj is Solid)
                                    //Solids.Add(IFCSolidInfo.Create(Solids[solidIdx].Id, geomObj as Solid));
                                    //else if (geomObj is Mesh)
                                    //Solids.Add(IFCSolidInfo.Create(Solids[solidIdx].Id, geomObj as Mesh));
                                    //else if (geomObj is GeometryInstance)
                                    //IFCImportFile.TheLog.LogError(Solids[solidIdx].Id, "Can't cut nested mapped items, ignoring " + numVoids + " void(s).", false);

                                    // Other items are irrelevant here.
                                    //}

                                    //Solids.RemoveAt(solidIdx);
                                    //solidIdx--;
                                    //numSolids--;
                                }
                            }

                            // This may be different than before, with the addition of solids from FamilyInstances.
                            numSolids = Solids.Count;

                            // Attempt to cut each solid with each void.
                            for (int solidIdx = 0; solidIdx < numSolids; solidIdx++)
                            {
                                if (!(Solids[solidIdx].GeometryObject is Solid))
                                {
                                    // Assume that we only deal with solids, meshes and instances.
                                    string typeName = (Solids[solidIdx].GeometryObject is Mesh) ? "mesh" : "instance";
                                    IFCImportFile.TheLog.LogError(Id, "Can't cut " + typeName + " geometry, ignoring " + numVoids + " void(s).", false);
                                    continue;
                                }

                                for (int voidIdx = 0; voidIdx < numVoids; voidIdx++)
                                {
                                    if (!(Voids[voidIdx].GeometryObject is Solid))
                                    {
                                        IFCImportFile.TheLog.LogError(Id, "Can't cut Solid geometry with a Mesh (# " + Voids[voidIdx].Id + "), ignoring.", false);
                                        continue;
                                    }

                                    Solids[solidIdx].GeometryObject =
                                        IFCGeometryUtil.ExecuteSafeBooleanOperation(Solids[solidIdx].Id, Voids[voidIdx].Id,
                                                                                    Solids[solidIdx].GeometryObject as Solid, Voids[voidIdx].GeometryObject as Solid,
                                                                                    BooleanOperationsType.Difference);
                                    if ((Solids[solidIdx].GeometryObject as Solid).Faces.IsEmpty)
                                    {
                                        Solids.RemoveAt(solidIdx);
                                        solidIdx--;
                                        numSolids--;
                                        break;
                                    }
                                }
                            }
                        }

                        bool addedCurves = shapeEditScope.AddPlanViewCurves(FootprintCurves, Id);

                        if ((numSolids > 0 || addedCurves))
                        {
                            if (GlobalId != null)
                            {
                                // If the GlobalId is null, this is a fake IfcProduct that we don't want to create into a DirectShape, or
                                // add to the caches in any way.  We only wanted to gather its geometry.
                                DirectShape shape = Importer.TheCache.UseElementByGUID <DirectShape>(doc, GlobalId);

                                if (shape == null)
                                {
                                    shape = IFCElementUtil.CreateElement(doc, CategoryId, Importer.ImportAppGUID(), GlobalId);
                                }

                                List <GeometryObject> directShapeGeometries = new List <GeometryObject>();
                                foreach (IFCSolidInfo geometryObject in Solids)
                                {
                                    // We need to check if the solid created is good enough for DirectShape.  If not, warn and use a fallback Mesh.
                                    GeometryObject currObject = geometryObject.GeometryObject;
                                    if (currObject is Solid)
                                    {
                                        Solid solid = currObject as Solid;
                                        if (!shape.IsValidGeometry(solid))
                                        {
                                            IFCImportFile.TheLog.LogWarning(Id, "Couldn't create valid solid, reverting to mesh.", false);
                                            directShapeGeometries.AddRange(IFCGeometryUtil.CreateMeshesFromSolid(solid));
                                            currObject = null;
                                        }
                                    }

                                    if (currObject != null)
                                    {
                                        directShapeGeometries.Add(currObject);
                                    }
                                }

                                // We will use the first IfcTypeObject id, if it exists.  In general, there should be 0 or 1.
                                ElementId typeId = ElementId.InvalidElementId;
                                foreach (IFCTypeObject typeObject in TypeObjects)
                                {
                                    if (typeObject.IsValidForCreation && typeObject.CreatedElementId != ElementId.InvalidElementId)
                                    {
                                        typeId = typeObject.CreatedElementId;
                                        break;
                                    }
                                }

                                shape.SetShape(directShapeGeometries);
                                shapeEditScope.SetPlanViewRep(shape);

                                if (typeId != ElementId.InvalidElementId)
                                {
                                    shape.SetTypeId(typeId);
                                }

                                PresentationLayerNames.UnionWith(shapeEditScope.PresentationLayerNames);
                                m_CreatedElementId = shape.Id;
                            }
                        }
                    }
                }
                else
                {
                    IFCImportFile.TheLog.LogWarning(Id, "There is no valid geometry for this " + EntityType.ToString() + "; entity will not be built.", false);
                }
            }

            base.Create(doc);
        }
예제 #7
0
        /// <summary>
        /// Creates or populates Revit elements based on the information contained in this class.
        /// </summary>
        /// <param name="doc">The document.</param>
        protected virtual void TraverseSubElements(Document doc)
        {
            IList <ElementId> subElementIds = new List <ElementId>();

            // These two should only be populated if GroupSubElements() is true and we are duplicating geometry for containers.
            List <GeometryObject> groupedSubElementGeometries      = new List <GeometryObject>();
            List <Curve>          groupedSubElementFootprintCurves = new List <Curve>();

            if (ComposedObjectDefinitions != null)
            {
                foreach (IFCObjectDefinition objectDefinition in ComposedObjectDefinitions)
                {
                    IFCObjectDefinition.CreateElement(doc, objectDefinition);
                    if (objectDefinition.CreatedElementId != ElementId.InvalidElementId)
                    {
                        subElementIds.Add(objectDefinition.CreatedElementId);

                        // CreateDuplicateContainerGeometry is currently an API-only option (no UI), set to true by default.
                        if (GroupSubElements() && Importer.TheOptions.CreateDuplicateContainerGeometry)
                        {
                            IList <GeometryObject> subGeometries = GetOrCloneGeometry(doc, objectDefinition);
                            if (subGeometries != null)
                            {
                                groupedSubElementGeometries.AddRange(subGeometries);
                            }

                            if (objectDefinition is IFCProduct)
                            {
                                groupedSubElementFootprintCurves.AddRange((objectDefinition as IFCProduct).FootprintCurves);
                            }
                        }
                    }
                }
            }

            if (GroupSubElements())
            {
                if (subElementIds.Count > 0)
                {
                    if (CreatedElementId != ElementId.InvalidElementId)
                    {
                        subElementIds.Add(CreatedElementId);
                    }

                    // We aren't yet actually grouping the elements.  DirectShape doesn't support grouping, and
                    // the Group element doesn't support adding parameters.  For now, we will create a DirectShape that "forgets"
                    // the association, which is good enough for link.
                    DirectShape directShape = IFCElementUtil.CreateElement(doc, CategoryId, GlobalId, groupedSubElementGeometries);
                    //Group group = doc.Create.NewGroup(subElementIds);

                    if (directShape != null)
                    {
                        CreatedElementId = directShape.Id;
                        CreatedGeometry  = groupedSubElementGeometries;

                        if (groupedSubElementFootprintCurves.Count != 0 && this is IFCProduct)
                        {
                            using (IFCImportShapeEditScope planViewScope = IFCImportShapeEditScope.Create(doc, this as IFCProduct))
                            {
                                planViewScope.AddPlanViewCurves(groupedSubElementFootprintCurves, Id);
                                planViewScope.SetPlanViewRep(directShape);
                            }
                        }
                    }
                    else
                    {
                        Importer.TheLog.LogCreationError(this, null, false);
                    }
                }
            }
        }
예제 #8
0
        /// <summary>
        /// Creates or populates Revit elements based on the information contained in this class.
        /// </summary>
        /// <param name="doc">The document.</param>
        protected virtual void TraverseSubElements(Document doc)
        {
            IList <ElementId> subElementIds = new List <ElementId>();

            // These two should only be populated if GroupSubElements() is true and we are duplicating
            // geometry for containers.
            List <GeometryObject> groupedSubElementGeometries      = new List <GeometryObject>();
            List <Curve>          groupedSubElementFootprintCurves = new List <Curve>();

            foreach (IFCObjectDefinition objectDefinition in ComposedObjectDefinitions)
            {
                CreateElement(doc, objectDefinition);
                if (objectDefinition.CreatedElementId == ElementId.InvalidElementId)
                {
                    continue;
                }

                subElementIds.Add(objectDefinition.CreatedElementId);

                // CreateDuplicateContainerGeometry is currently an API-only option (no UI), set to true by default.
                //
                // NAVIS_TODO - This is wrong if Importer.TheProcessor.ApplyTransforms is false
                if (!GroupSubElements() || !Importer.TheOptions.CreateDuplicateContainerGeometry)
                {
                    continue;
                }

                IList <GeometryObject> subGeometries = GetOrCloneGeometry(doc, objectDefinition);
                if (subGeometries != null)
                {
                    groupedSubElementGeometries.AddRange(subGeometries);
                }

                if (objectDefinition is IFCProduct)
                {
                    groupedSubElementFootprintCurves.AddRange((objectDefinition as IFCProduct).FootprintCurves);
                }
            }

            if (groupedSubElementGeometries.Count > 0)
            {
                // Add main element geometry to include it in direct shape
                // and be able to assign parameters to the whole geometry and not just to subelements
                IList <GeometryObject> elementGeometry = GetOrCloneGeometry(doc, this);
                if ((elementGeometry?.Count ?? 0) > 0)
                {
                    groupedSubElementGeometries.AddRange(elementGeometry);
                    Importer.TheLog.LogWarning(Id, "Entity contains both geometry and sub-entities with geometry. This may result in duplicate geometry.", false);
                }
            }

            if (GroupSubElements())
            {
                if (subElementIds.Count > 0)
                {
                    if (CreatedElementId != ElementId.InvalidElementId && groupedSubElementGeometries.Count == 0)
                    {
                        // If CreateDuplicateContainerGeometry is false,  then
                        // groupedSubElementGeometries is empty and we then create a new
                        // DirectShape with no content in it.
                        //
                        // For files such as NW-55644 that has geometry on the slab element and
                        // children with geometry, this means that the slab geometry is thrown away
                        return;
                    }

                    if (CreatedElementId != ElementId.InvalidElementId)
                    {
                        subElementIds.Add(CreatedElementId);
                    }

                    // We aren't yet actually grouping the elements.  DirectShape doesn't support grouping, and
                    // the Group element doesn't support adding parameters.  For now, we will create a DirectShape that "forgets"
                    // the association, which is good enough for link.
                    DirectShape directShape = IFCElementUtil.CreateElement(doc, CategoryId, GlobalId, groupedSubElementGeometries, Id, EntityType);
                    //Group group = doc.Create.NewGroup(subElementIds);

                    if (directShape != null)
                    {
                        CreatedElementId = directShape.Id;
                        CreatedGeometry  = groupedSubElementGeometries;

                        if (groupedSubElementFootprintCurves.Count != 0 && this is IFCProduct)
                        {
                            using (IFCImportShapeEditScope planViewScope = IFCImportShapeEditScope.Create(doc, this as IFCProduct))
                            {
                                planViewScope.AddPlanViewCurves(groupedSubElementFootprintCurves, Id);
                                planViewScope.SetPlanViewRep(directShape);
                            }
                        }
                    }
                    else
                    {
                        Importer.TheLog.LogCreationError(this, null, false);
                    }
                }
            }
        }
예제 #9
0
        /// <summary>
        /// Creates or populates Revit elements based on the information contained in this class.
        /// </summary>
        /// <param name="doc">The document.</param>
        protected override void Create(Document doc)
        {
            Transform lcs = (ObjectLocation != null) ? ObjectLocation.TotalTransform : Transform.Identity;

            // 2016+ only.
            Point point = Point.Create(lcs.Origin, GraphicsStyleId);

            // 2015+: create cone(s) for the direction of flow.
            CurveLoop    rightTrangle = new CurveLoop();
            const double radius       = 0.5 / 12.0;
            const double height       = 1.5 / 12.0;

            SolidOptions solidOptions = new SolidOptions(ElementId.InvalidElementId, GraphicsStyleId);

            Frame coordinateFrame = new Frame(lcs.Origin, lcs.BasisX, lcs.BasisY, lcs.BasisZ);

            // The origin is at the base of the cone for everything but source - then it is at the top of the cone.
            XYZ pt1 = FlowDirection == IFCFlowDirection.Source ? lcs.Origin - height * lcs.BasisZ : lcs.Origin;
            XYZ pt2 = pt1 + radius * lcs.BasisX;
            XYZ pt3 = pt1 + height * lcs.BasisZ;

            rightTrangle.Append(Line.CreateBound(pt1, pt2));
            rightTrangle.Append(Line.CreateBound(pt2, pt3));
            rightTrangle.Append(Line.CreateBound(pt3, pt1));
            IList <CurveLoop> curveLoops = new List <CurveLoop>();

            curveLoops.Add(rightTrangle);

            Solid portArrow = GeometryCreationUtilities.CreateRevolvedGeometry(coordinateFrame, curveLoops, 0.0, Math.PI * 2.0, solidOptions);

            Solid oppositePortArrow = null;

            if (FlowDirection == IFCFlowDirection.SourceAndSink)
            {
                Frame     oppositeCoordinateFrame = new Frame(lcs.Origin, -lcs.BasisX, lcs.BasisY, -lcs.BasisZ);
                CurveLoop oppositeRightTrangle    = new CurveLoop();

                XYZ oppPt2 = pt1 - radius * lcs.BasisX;
                XYZ oppPt3 = pt1 - height * lcs.BasisZ;
                oppositeRightTrangle.Append(Line.CreateBound(pt1, oppPt2));
                oppositeRightTrangle.Append(Line.CreateBound(oppPt2, oppPt3));
                oppositeRightTrangle.Append(Line.CreateBound(oppPt3, pt1));
                IList <CurveLoop> oppositeCurveLoops = new List <CurveLoop>();
                oppositeCurveLoops.Add(oppositeRightTrangle);

                oppositePortArrow = GeometryCreationUtilities.CreateRevolvedGeometry(oppositeCoordinateFrame, oppositeCurveLoops, 0.0, Math.PI * 2.0, solidOptions);
            }

            if (portArrow != null)
            {
                IList <GeometryObject> geomObjs = new List <GeometryObject>();

                if (point != null)
                {
                    geomObjs.Add(point);
                }
                geomObjs.Add(portArrow);
                if (oppositePortArrow != null)
                {
                    geomObjs.Add(oppositePortArrow);
                }

                DirectShape directShape = IFCElementUtil.CreateElement(doc, CategoryId, GlobalId, geomObjs, Id);
                if (directShape != null)
                {
                    CreatedGeometry  = geomObjs;
                    CreatedElementId = directShape.Id;
                }
                else
                {
                    Importer.TheLog.LogCreationError(this, null, false);
                }
            }
        }
예제 #10
0
        /// <summary>
        /// Creates or populates Revit elements based on the information contained in this class.
        /// </summary>
        /// <param name="doc">The document.</param>
        protected override void Create(Document doc)
        {
            bool       preventInstances = false;
            IFCElement element          = this as IFCElement;

            if (element != null)
            {
                preventInstances = this is IFCOpeningElement;
                foreach (IFCFeatureElement opening in element.Openings)
                {
                    try
                    {
                        preventInstances = true;
                        // Create the actual Revit element based on the IFCFeatureElement here.
                        ElementId openingId = CreateElement(doc, opening);

                        // This gets around the issue that the Boolean operation between the void(s) in the IFCFeatureElement and
                        // the solid(s) in the IFCElement may use the Graphics Style of the voids in the resulting Solid(s), meaning
                        // that some faces may disappear when we turn off the visibility of IfcOpeningElements.
                        IList <IFCSolidInfo> voids = IFCElement.CloneElementGeometry(doc, opening, this, true);
                        if (voids != null)
                        {
                            foreach (IFCSolidInfo voidGeom in voids)
                            {
                                IFCVoidInfo voidInfo = new IFCVoidInfo(voidGeom);
                                if (!Importer.TheProcessor.ApplyTransforms)
                                {
                                    // If we aren't applying transforms, then the Voids and Solids will be
                                    // in different coordinate spaces, so we need the transform of the
                                    // void, so we can transform it into the Solid coordinate space
                                    voidInfo.TotalTransform = opening?.ObjectLocation?.TotalTransform;
                                }

                                Voids.Add(voidInfo);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Importer.TheLog.LogError(opening.Id, ex.Message, false);
                    }
                }
            }
            if (HasValidTopLevelGeometry())
            {
                using (IFCImportShapeEditScope shapeEditScope = IFCImportShapeEditScope.Create(doc, this))
                {
                    shapeEditScope.GraphicsStyleId  = GraphicsStyleId;
                    shapeEditScope.CategoryId       = CategoryId;
                    shapeEditScope.PreventInstances = preventInstances;

                    // The name can be added as well. but it is usually less useful than 'oid'
                    string myId = GlobalId; // + "(" + Name + ")";

                    Transform lcs = IFCImportFile.TheFile.IFCProject.WorldCoordinateSystem;
                    if (lcs == null)
                    {
                        lcs = (ObjectLocation != null) ? ObjectLocation.TotalTransform : Transform.Identity;
                    }
                    else if (ObjectLocation != null)
                    {
                        lcs = lcs.Multiply(ObjectLocation.TotalTransform);
                    }

                    // If we are not applying transforms to the geometry, then pass in the identity matrix.
                    // Lower down this method we then pass lcs to the consumer element, so that it can apply
                    // the transform as required.
                    Transform transformToUse = Importer.TheProcessor.ApplyTransforms ? lcs : Transform.Identity;
                    ProductRepresentation.CreateProductRepresentation(shapeEditScope, transformToUse, transformToUse, myId);

                    int numSolids = Solids.Count;
                    // Attempt to cut each solid with each void.
                    for (int solidIdx = 0; solidIdx < numSolids; solidIdx++)
                    {
                        if (!CutSolidByVoids(Solids[solidIdx]))
                        {
                            Solids.RemoveAt(solidIdx);
                            solidIdx--;
                            numSolids--;
                        }
                    }

                    bool addedCurves = shapeEditScope.AddPlanViewCurves(FootprintCurves, Id);

                    if ((numSolids > 0 || addedCurves))
                    {
                        if (GlobalId != null)
                        {
                            // If the GlobalId is null, this is a fake IfcProduct that we don't want to create into a DirectShape, or
                            // add to the caches in any way.  We only wanted to gather its geometry.
                            DirectShape shape = Importer.TheCache.UseElementByGUID <DirectShape>(doc, GlobalId);

                            if (shape == null)
                            {
                                shape = IFCElementUtil.CreateElement(doc, CategoryId, GlobalId, null, Id, EntityType);
                            }

                            List <GeometryObject> directShapeGeometries = new List <GeometryObject>();
                            foreach (IFCSolidInfo geometryObject in Solids)
                            {
                                // We need to check if the solid created is good enough for DirectShape.  If not, warn and use a fallback Mesh.
                                GeometryObject currObject = geometryObject.GeometryObject;
                                if (currObject is Solid)
                                {
                                    Solid solid = currObject as Solid;
                                    if (!shape.IsValidGeometry(solid))
                                    {
                                        Importer.TheLog.LogWarning(Id, "Couldn't create valid solid, reverting to mesh.", false);
                                        directShapeGeometries.AddRange(IFCGeometryUtil.CreateMeshesFromSolid(solid));
                                        currObject = null;
                                    }
                                }

                                if (currObject != null)
                                {
                                    directShapeGeometries.Add(currObject);
                                }
                            }

                            // We will use the first IfcTypeObject id, if it exists.  In general, there should be 0 or 1.
                            IFCTypeObject typeObjectToUse = null;
                            foreach (IFCTypeObject typeObject in TypeObjects)
                            {
                                if (typeObject.IsValidForCreation && typeObject.CreatedElementId != ElementId.InvalidElementId)
                                {
                                    typeObjectToUse = typeObject;
                                    break;
                                }
                            }

                            if (!Importer.TheProcessor.PostProcessProduct(Id, typeObjectToUse?.Id, lcs,
                                                                          directShapeGeometries))
                            {
                                if (shape != null)
                                {
                                    shape.SetShape(directShapeGeometries);
                                    shapeEditScope.SetPlanViewRep(shape);

                                    if (typeObjectToUse != null && typeObjectToUse.CreatedElementId != ElementId.InvalidElementId)
                                    {
                                        shape.SetTypeId(typeObjectToUse.CreatedElementId);
                                    }
                                }
                            }

                            PresentationLayerNames.UnionWith(shapeEditScope.PresentationLayerNames);

                            CreatedElementId = shape.Id;
                            CreatedGeometry  = directShapeGeometries;
                        }
                    }
                }
            }
            else
            {
                if (this is IFCElement || this is IFCGrid)
                {
                    IList <IFCEntity> visitedEntities = new List <IFCEntity>();
                    visitedEntities.Add(this);
                    if (!HasValidSubElementGeometry(visitedEntities))
                    {
                        // We will not warn if this is an IfcSpatialStructureElement; those aren't expected to have their own geometry.
                        Importer.TheLog.LogWarning(Id, "There is no valid geometry for this " + EntityType.ToString() + "; entity will not be built.", false);
                    }
                }
            }

            base.Create(doc);
        }
예제 #11
0
        /// <summary>
        /// Creates or populates Revit elements based on the information contained in this class.
        /// </summary>
        /// <param name="doc">The document.</param>
        protected override void Create(Document doc)
        {
            bool       preventInstances = false;
            IFCElement element          = this as IFCElement;

            if (element != null)
            {
                IFCOpeningElement openingElement = element as IFCOpeningElement;
                if (openingElement != null)
                {
                    preventInstances = true;
                }
                foreach (IFCFeatureElement opening in element.Openings)
                {
                    try
                    {
                        preventInstances = true;
                        // Create the actual Revit element based on the IFCFeatureElement here.
                        ElementId openingId = CreateElement(doc, opening);

                        // This gets around the issue that the Boolean operation between the void(s) in the IFCFeatureElement and
                        // the solid(s) in the IFCElement may use the Graphics Style of the voids in the resulting Solid(s), meaning
                        // that some faces may disappear when we turn off the visibility of IfcOpeningElements.
                        IList <IFCSolidInfo> voids = IFCElement.CloneElementGeometry(doc, opening, this, true);
                        if (voids != null)
                        {
                            foreach (IFCSolidInfo voidGeom in voids)
                            {
                                Voids.Add(voidGeom);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Importer.TheLog.LogError(opening.Id, ex.Message, false);
                    }
                }
            }
            if (HasValidTopLevelGeometry())
            {
                using (IFCImportShapeEditScope shapeEditScope = IFCImportShapeEditScope.Create(doc, this))
                {
                    shapeEditScope.GraphicsStyleId  = GraphicsStyleId;
                    shapeEditScope.CategoryId       = CategoryId;
                    shapeEditScope.PreventInstances = preventInstances;
                    // The name can be added as well. but it is usually less useful than 'oid'
                    string myId = GlobalId; // + "(" + Name + ")";

                    Transform lcs = IFCImportFile.TheFile.IFCProject.WorldCoordinateSystem;
                    if (lcs == null)
                    {
                        lcs = (ObjectLocation != null) ? ObjectLocation.TotalTransform : Transform.Identity;
                    }
                    else if (ObjectLocation != null)
                    {
                        lcs = lcs.Multiply(ObjectLocation.TotalTransform);
                    }

                    ProductRepresentation.CreateProductRepresentation(shapeEditScope, lcs, lcs, myId);

                    int numSolids = Solids.Count;
                    int numVoids  = Voids.Count;
                    if ((numSolids > 0) && (numVoids > 0))
                    {
                        // This may be different than before, with the addition of solids from FamilyInstances.
                        numSolids = Solids.Count;

                        // Attempt to cut each solid with each void.
                        for (int solidIdx = 0; solidIdx < numSolids; solidIdx++)
                        {
                            // We only cut body representation items.
                            if (Solids[solidIdx].RepresentationType != IFCRepresentationIdentifier.Body)
                            {
                                continue;
                            }

                            if (!(Solids[solidIdx].GeometryObject is Solid))
                            {
                                string typeName = (Solids[solidIdx].GeometryObject is Mesh) ? "mesh" : "instance";
                                Importer.TheLog.LogError(Id, "Can't cut " + typeName + " geometry, ignoring " + numVoids + " void(s).", false);
                                continue;
                            }

                            for (int voidIdx = 0; voidIdx < numVoids; voidIdx++)
                            {
                                if (!(Voids[voidIdx].GeometryObject is Solid))
                                {
                                    Importer.TheLog.LogError(Id, "Can't cut Solid geometry with a Mesh (# " + Voids[voidIdx].Id + "), ignoring.", false);
                                    continue;
                                }

                                Solids[solidIdx].GeometryObject =
                                    IFCGeometryUtil.ExecuteSafeBooleanOperation(Solids[solidIdx].Id, Voids[voidIdx].Id,
                                                                                Solids[solidIdx].GeometryObject as Solid, Voids[voidIdx].GeometryObject as Solid,
                                                                                BooleanOperationsType.Difference, null);
                                if ((Solids[solidIdx].GeometryObject as Solid).Faces.IsEmpty)
                                {
                                    Solids.RemoveAt(solidIdx);
                                    solidIdx--;
                                    numSolids--;
                                    break;
                                }
                            }
                        }
                    }

                    bool addedCurves = shapeEditScope.AddPlanViewCurves(FootprintCurves, Id);

                    if ((numSolids > 0 || addedCurves))
                    {
                        if (GlobalId != null)
                        {
                            // If the GlobalId is null, this is a fake IfcProduct that we don't want to create into a DirectShape, or
                            // add to the caches in any way.  We only wanted to gather its geometry.
                            DirectShape shape = Importer.TheCache.UseElementByGUID <DirectShape>(doc, GlobalId);

                            if (shape == null)
                            {
                                shape = IFCElementUtil.CreateElement(doc, CategoryId, GlobalId, null, Id);
                            }

                            List <GeometryObject> directShapeGeometries = new List <GeometryObject>();
                            foreach (IFCSolidInfo geometryObject in Solids)
                            {
                                // We need to check if the solid created is good enough for DirectShape.  If not, warn and use a fallback Mesh.
                                GeometryObject currObject = geometryObject.GeometryObject;
                                if (currObject is Solid)
                                {
                                    Solid solid = currObject as Solid;
                                    if (!shape.IsValidGeometry(solid))
                                    {
                                        Importer.TheLog.LogWarning(Id, "Couldn't create valid solid, reverting to mesh.", false);
                                        directShapeGeometries.AddRange(IFCGeometryUtil.CreateMeshesFromSolid(solid));
                                        currObject = null;
                                    }
                                }

                                if (currObject != null)
                                {
                                    directShapeGeometries.Add(currObject);
                                }
                            }

                            // We will use the first IfcTypeObject id, if it exists.  In general, there should be 0 or 1.
                            ElementId typeId = ElementId.InvalidElementId;
                            foreach (IFCTypeObject typeObject in TypeObjects)
                            {
                                if (typeObject.IsValidForCreation && typeObject.CreatedElementId != ElementId.InvalidElementId)
                                {
                                    typeId = typeObject.CreatedElementId;
                                    break;
                                }
                            }

                            shape.SetShape(directShapeGeometries);
                            shapeEditScope.SetPlanViewRep(shape);

                            if (typeId != ElementId.InvalidElementId)
                            {
                                shape.SetTypeId(typeId);
                            }

                            PresentationLayerNames.UnionWith(shapeEditScope.PresentationLayerNames);

                            CreatedElementId = shape.Id;
                            CreatedGeometry  = directShapeGeometries;
                        }
                    }
                }
            }
            else
            {
                if (this is IFCElement || this is IFCGrid)
                {
                    IList <IFCEntity> visitedEntities = new List <IFCEntity>();
                    visitedEntities.Add(this);
                    if (!HasValidSubElementGeometry(visitedEntities))
                    {
                        // We will not warn if this is an IfcSpatialStructureElement; those aren't expected to have their own geometry.
                        Importer.TheLog.LogWarning(Id, "There is no valid geometry for this " + EntityType.ToString() + "; entity will not be built.", false);
                    }
                }
            }

            base.Create(doc);
        }
        /// <summary>
        /// Create geometry for a particular representation map.
        /// </summary>
        /// <param name="shapeEditScope">The geometry creation scope.</param>
        /// <param name="lcs">Local coordinate system for the geometry, without scale.</param>
        /// <param name="scaledLcs">Local coordinate system for the geometry, including scale, potentially non-uniform.</param>
        /// <remarks>For this function, if lcs is null, we will create a library item for the geometry.</remarks>
        public void CreateShape(IFCImportShapeEditScope shapeEditScope, Transform lcs, Transform scaledLcs, string guid)
        {
            bool creatingLibraryDefinition = (lcs == null);

            if (MappedRepresentation != null)
            {
                // Look for cached shape; if found, return.
                if (creatingLibraryDefinition)
                {
                    if (IFCImportFile.TheFile.ShapeLibrary.FindDefinitionType(Id.ToString()) != ElementId.InvalidElementId)
                    {
                        return;
                    }
                }

                Transform mappingTransform = null;
                if (lcs == null)
                {
                    mappingTransform = MappingOrigin;
                }
                else
                {
                    if (MappingOrigin == null)
                    {
                        mappingTransform = lcs;
                    }
                    else
                    {
                        mappingTransform = lcs.Multiply(MappingOrigin);
                    }
                }

                Transform scaledMappingTransform = null;
                if (scaledLcs == null)
                {
                    scaledMappingTransform = mappingTransform;
                }
                else
                {
                    if (MappingOrigin == null)
                    {
                        scaledMappingTransform = scaledLcs;
                    }
                    else
                    {
                        scaledMappingTransform = scaledLcs.Multiply(MappingOrigin);
                    }
                }

                int numExistingSolids = shapeEditScope.Creator.Solids.Count;
                int numExistingCurves = shapeEditScope.Creator.FootprintCurves.Count;

                MappedRepresentation.CreateShape(shapeEditScope, mappingTransform, scaledMappingTransform, guid);

                if (creatingLibraryDefinition)
                {
                    int numNewSolids = shapeEditScope.Creator.Solids.Count;
                    int numNewCurves = shapeEditScope.Creator.FootprintCurves.Count;

                    if ((numExistingSolids != numNewSolids) || (numExistingCurves != numNewCurves))
                    {
                        IList <GeometryObject> mappedSolids = new List <GeometryObject>();
                        for (int ii = numExistingSolids; ii < numNewSolids; ii++)
                        {
                            mappedSolids.Add(shapeEditScope.Creator.Solids[numExistingSolids].GeometryObject);
                            shapeEditScope.Creator.Solids.RemoveAt(numExistingSolids);
                        }

                        IList <Curve> mappedCurves = new List <Curve>();
                        for (int ii = numExistingCurves; ii < numNewCurves; ii++)
                        {
                            mappedCurves.Add(shapeEditScope.Creator.FootprintCurves[numExistingCurves]);
                            shapeEditScope.Creator.FootprintCurves.RemoveAt(numExistingCurves);
                        }
                        shapeEditScope.AddPlanViewCurves(mappedCurves, Id);

                        //IFCImportFile.TheFile.ShapeLibrary.AddDefinition(Id.ToString(), mappedItems);

                        Document        doc             = IFCImportFile.TheFile.Document;
                        DirectShapeType directShapeType = DirectShapeType.Create(doc, Id.ToString(), IFCElementUtil.GetDSValidCategoryId(doc, shapeEditScope.CategoryId, Id));
                        directShapeType.SetShape(mappedSolids);
                        shapeEditScope.SetPlanViewRep(directShapeType);

                        IFCImportFile.TheFile.ShapeLibrary.AddDefinitionType(Id.ToString(), directShapeType.Id);
                    }
                }
            }
        }
예제 #13
0
        /// <summary>
        /// Creates or populates Revit elements based on the information contained in this class.
        /// </summary>
        /// <param name="doc">The document.</param>
        protected override void Create(Document doc)
        {
            // Try to get the location:
            // 1. From the ObjectLocation, if it exists.  This should be exact.
            // 2. From the ObjectLocation of the element that the port is associated to, if it exists.
            // This should be approximate.
            // 3. Default to the origin.
            Transform lcs = ObjectLocation?.TotalTransform;

            if (lcs == null)
            {
                lcs = ContainedIn?.ObjectLocation?.TotalTransform;
            }
            if (lcs == null)
            {
                lcs = Transform.Identity;
            }

            // 2016+ only.
            XYZ   origin = lcs.Origin;
            Point point  = XYZ.IsWithinLengthLimits(origin) ? Point.Create(origin, GraphicsStyleId) : null;

            // 2015+: create cone(s) for the direction of flow.
            CurveLoop    rightTrangle = new CurveLoop();
            const double radius       = 0.04;
            const double height       = 0.12;

            SolidOptions solidOptions = new SolidOptions(ElementId.InvalidElementId, GraphicsStyleId);

            Frame coordinateFrame = new Frame(lcs.Origin, lcs.BasisX, lcs.BasisY, lcs.BasisZ);

            // The origin is at the base of the cone for everything but source - then it is at the top of the cone.
            XYZ pt1 = FlowDirection == IFCFlowDirection.Source ? lcs.Origin - height * lcs.BasisZ : lcs.Origin;
            XYZ pt2 = pt1 + radius * lcs.BasisX;
            XYZ pt3 = pt1 + height * lcs.BasisZ;

            rightTrangle.Append(Line.CreateBound(pt1, pt2));
            rightTrangle.Append(Line.CreateBound(pt2, pt3));
            rightTrangle.Append(Line.CreateBound(pt3, pt1));
            IList <CurveLoop> curveLoops = new List <CurveLoop>();

            curveLoops.Add(rightTrangle);

            Solid portArrow = GeometryCreationUtilities.CreateRevolvedGeometry(coordinateFrame, curveLoops, 0.0, Math.PI * 2.0, solidOptions);

            Solid oppositePortArrow = null;

            if (FlowDirection == IFCFlowDirection.SourceAndSink)
            {
                Frame     oppositeCoordinateFrame = new Frame(lcs.Origin, -lcs.BasisX, lcs.BasisY, -lcs.BasisZ);
                CurveLoop oppositeRightTrangle    = new CurveLoop();

                XYZ oppPt2 = pt1 - radius * lcs.BasisX;
                XYZ oppPt3 = pt1 - height * lcs.BasisZ;
                oppositeRightTrangle.Append(Line.CreateBound(pt1, oppPt2));
                oppositeRightTrangle.Append(Line.CreateBound(oppPt2, oppPt3));
                oppositeRightTrangle.Append(Line.CreateBound(oppPt3, pt1));
                IList <CurveLoop> oppositeCurveLoops = new List <CurveLoop>();
                oppositeCurveLoops.Add(oppositeRightTrangle);

                oppositePortArrow = GeometryCreationUtilities.CreateRevolvedGeometry(oppositeCoordinateFrame, oppositeCurveLoops, 0.0, Math.PI * 2.0, solidOptions);
            }

            if (portArrow != null)
            {
                IList <GeometryObject> geomObjs = new List <GeometryObject>();

                if (point != null)
                {
                    geomObjs.Add(point);
                }
                geomObjs.Add(portArrow);
                if (oppositePortArrow != null)
                {
                    geomObjs.Add(oppositePortArrow);
                }

                DirectShape directShape = IFCElementUtil.CreateElement(doc, CategoryId, GlobalId, geomObjs, Id, EntityType);
                if (directShape != null)
                {
                    CreatedGeometry  = geomObjs;
                    CreatedElementId = directShape.Id;
                }
                else
                {
                    Importer.TheLog.LogCreationError(this, null, false);
                }
            }
        }