override protected void Process(IFCAnyHandle ifcPolyLoop) { base.Process(ifcPolyLoop); List<IFCAnyHandle> ifcPolygon = IFCAnyHandleUtil.GetAggregateInstanceAttribute<List<IFCAnyHandle>>(ifcPolyLoop, "Polygon"); if (ifcPolygon == null) return; // TODO: WARN Polygon = IFCPoint.ProcessScaledLengthIFCCartesianPoints(ifcPolygon); int numVertices = Polygon.Count; if (numVertices > 1) { if (Polygon[0].IsAlmostEqualTo(Polygon[numVertices - 1])) { // LOG: Warning: #: First and last points are almost identical, removing extra point. Polygon.RemoveAt(numVertices - 1); numVertices--; } } if (numVertices < 3) throw new InvalidOperationException("#" + ifcPolyLoop.StepId + ": Polygon attribute has only " + numVertices + " vertices, 3 expected."); }
override protected void Process(IFCAnyHandle item) { base.Process(item); HashSet<IFCData> styles = IFCAnyHandleUtil.GetAggregateAttribute<HashSet<IFCData>>(item, "Styles"); if (styles != null) { foreach (IFCData styleData in styles) { if (styleData.PrimitiveType == IFCDataPrimitiveType.Instance) { IFCAnyHandle style = styleData.AsInstance(); try { IFCPresentationStyle presentationStyle = IFCPresentationStyle.ProcessIFCPresentationStyle(style); if (presentationStyle != null) Styles.Add(presentationStyle); } catch (Exception ex) { Importer.TheLog.LogError(item.StepId, ex.Message, false); } } } } }
/// <summary> /// Adds the handle to the dictionary. /// </summary> /// <param name="elementId"> /// The element elementId. /// </param> /// <param name="handle"> /// The handle. /// </param> public void Register(ElementId elementId, IFCAnyHandle handle) { if (elementIdToHandleDictionary.ContainsKey(elementId)) return; elementIdToHandleDictionary[elementId] = handle; }
override protected void Process(IFCAnyHandle item) { base.Process(item); string booleanOperatorAsString = IFCAnyHandleUtil.GetEnumerationAttribute(item, "Operator"); if (!string.IsNullOrWhiteSpace(booleanOperatorAsString)) BooleanOperator = (IFCBooleanOperator)Enum.Parse(typeof(IFCBooleanOperator), booleanOperatorAsString, true); IFCAnyHandle firstOperand = IFCImportHandleUtil.GetRequiredInstanceAttribute(item, "FirstOperand", true); FirstOperand = IFCBooleanOperand.ProcessIFCBooleanOperand(firstOperand); IFCAnyHandle secondOperand = IFCImportHandleUtil.GetRequiredInstanceAttribute(item, "SecondOperand", true); // We'll allow a solid to be created even if the second operand can't be properly handled. try { SecondOperand = IFCBooleanOperand.ProcessIFCBooleanOperand(secondOperand); } catch (Exception ex) { SecondOperand = null; IFCImportFile.TheLog.LogError(secondOperand.StepId, ex.Message, false); } }
protected override void Process(IFCAnyHandle ifcCurve) { base.Process(ifcCurve); IFCAnyHandle basisCurve = IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcCurve, "BasisCurve", false); if (basisCurve == null) return; IFCAnyHandle dir = IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcCurve, "RefDirection", false); bool found = false; double distance = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(ifcCurve, "Distance", out found); if (!found) distance = 0.0; IFCCurve ifcBasisCurve = IFCCurve.ProcessIFCCurve(basisCurve); XYZ dirXYZ = (dir == null) ? ifcBasisCurve.GetNormal() : IFCPoint.ProcessNormalizedIFCDirection(dir); try { if (ifcBasisCurve.Curve != null) Curve = ifcBasisCurve.Curve.CreateOffset(distance, XYZ.BasisZ); else if (ifcBasisCurve.CurveLoop != null) CurveLoop = CurveLoop.CreateViaOffset(ifcBasisCurve.CurveLoop, distance, XYZ.BasisZ); } catch { Importer.TheLog.LogError(ifcCurve.StepId, "Couldn't create offset curve.", false); } }
/// <summary> /// Processes an IfcWindowLiningProperties entity. /// </summary> /// <param name="ifcWindowLiningProperties">The IfcWindowLiningProperties handle.</param> protected override void Process(IFCAnyHandle ifcWindowLiningProperties) { base.Process(ifcWindowLiningProperties); if (m_WindowLiningPropertyDescs == null) { m_WindowLiningPropertyDescs = new List<Tuple<string, UnitType, AllowedValues>>(); m_WindowLiningPropertyDescs.Add(new Tuple<string, UnitType, AllowedValues>("LiningDepth", UnitType.UT_Length, AllowedValues.Positive)); m_WindowLiningPropertyDescs.Add(new Tuple<string, UnitType, AllowedValues>("LiningThickness", UnitType.UT_Length, AllowedValues.Positive)); m_WindowLiningPropertyDescs.Add(new Tuple<string, UnitType, AllowedValues>("TransomThickness", UnitType.UT_Length, AllowedValues.Positive)); m_WindowLiningPropertyDescs.Add(new Tuple<string, UnitType, AllowedValues>("MullionThickness", UnitType.UT_Length, AllowedValues.Positive)); m_WindowLiningPropertyDescs.Add(new Tuple<string, UnitType, AllowedValues>("FirstTransomOffset", UnitType.UT_Length, AllowedValues.NonNegative)); m_WindowLiningPropertyDescs.Add(new Tuple<string, UnitType, AllowedValues>("SecondTransomOffset", UnitType.UT_Length, AllowedValues.NonNegative)); m_WindowLiningPropertyDescs.Add(new Tuple<string, UnitType, AllowedValues>("FirstMullionOffset", UnitType.UT_Length, AllowedValues.NonNegative)); m_WindowLiningPropertyDescs.Add(new Tuple<string, UnitType, AllowedValues>("SecondMullionOffset", UnitType.UT_Length, AllowedValues.NonNegative)); } for (int ii = 0; ii < 4; ii++) { Tuple<string, UnitType, AllowedValues> propertyDesc = m_WindowLiningPropertyDescs[ii]; // Default is nonsense value. double currPropertyValue = IFCImportHandleUtil.GetOptionalScaledLengthAttribute(ifcWindowLiningProperties, propertyDesc.Item1, -1e+30); if (!MathUtil.IsAlmostEqual(currPropertyValue , -1e+30)) DoubleProperties[propertyDesc] = currPropertyValue; } for (int ii = 4; ii < 8; ii++) { Tuple<string, UnitType, AllowedValues> propertyDesc = m_WindowLiningPropertyDescs[ii]; // Default is nonsense value. double currPropertyValue = IFCImportHandleUtil.GetOptionalDoubleAttribute(ifcWindowLiningProperties, propertyDesc.Item1, -1e+30); if (!MathUtil.IsAlmostEqual(currPropertyValue, -1e+30)) DoubleProperties[propertyDesc] = currPropertyValue; } }
/// <summary> /// Adds the IfcPresentationStyleAssignment handle to the dictionary. /// </summary> /// <param name="elementId"> /// The element elementId. /// </param> /// <param name="handle"> /// The IfcPresentationStyleAssignment handle. /// </param> public void Register(ElementId elementId, IFCAnyHandle handle) { if (m_Styles.ContainsKey(elementId.IntegerValue)) throw new Exception("TextStyleCache already contains handle for elementId " + elementId.IntegerValue); m_Styles[elementId.IntegerValue] = handle; }
override protected void Process(IFCAnyHandle item) { base.Process(item); LayerAssignment = IFCPresentationLayerAssignment.GetTheLayerAssignment(item); List<IFCAnyHandle> styledByItems = IFCAnyHandleUtil.GetAggregateInstanceAttribute<List<IFCAnyHandle>>(item, "StyledByItem"); if (styledByItems != null && styledByItems.Count > 0) { // We can only handle one styled item, but we allow the possiblity that there are duplicates. Do a top-level check. foreach (IFCAnyHandle styledByItem in styledByItems) { if (!IFCAnyHandleUtil.IsSubTypeOf(styledByItem, IFCEntityType.IfcStyledItem)) { Importer.TheLog.LogUnexpectedTypeError(styledByItem, IFCEntityType.IfcStyledItem, false); StyledByItem = null; break; } else { if (StyledByItem == null) StyledByItem = IFCStyledItem.ProcessIFCStyledItem(styledByItem); else { IFCStyledItem compStyledByItem = IFCStyledItem.ProcessIFCStyledItem(styledByItem); if (!StyledByItem.IsEquivalentTo(compStyledByItem)) { Importer.TheLog.LogWarning(Id, "Multiple inconsistent styled items found for this item; using first one.", false); break; } } } } } }
/// <summary> /// Creates a shape representation and register it to shape representation layer. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="contextOfItems">The context for which the different subtypes of representation are valid.</param> /// <param name="identifier">The identifier for the representation.</param> /// <param name="representationType">The type handle for the representation.</param> /// <param name="items">Collection of geometric representation items that are defined for this representation.</param> /// <returns>The handle.</returns> public static IFCAnyHandle CreateBaseShapeRepresentation(ExporterIFC exporterIFC, IFCAnyHandle contextOfItems, string identifier, string representationType, ISet<IFCAnyHandle> items) { IFCFile file = exporterIFC.GetFile(); IFCAnyHandle newShapeRepresentation = IFCInstanceExporter.CreateShapeRepresentation(file, contextOfItems, identifier, representationType, items); return newShapeRepresentation; }
/// <summary> /// Creates uniformat classification. /// </summary> /// <param name="exporterIFC">The ExporterIFC.</param> /// <param name="file">The file.</param> /// <param name="element">The element.</param> /// <param name="elemHnd">The element handle.</param> public static void CreateUniformatClassification(ExporterIFC exporterIFC, IFCFile file, Element element, IFCAnyHandle elemHnd) { // Create Uniformat classification, if it is not set. string uniformatKeyString = "Uniformat"; string uniformatCode = ""; if (ParameterUtil.GetStringValueFromElementOrSymbol(element, BuiltInParameter.UNIFORMAT_CODE, false, out uniformatCode) == null) ParameterUtil.GetStringValueFromElementOrSymbol(element, "Assembly Code", out uniformatCode); string uniformatDescription = ""; if (!String.IsNullOrWhiteSpace(uniformatCode)) { if (ParameterUtil.GetStringValueFromElementOrSymbol(element, BuiltInParameter.UNIFORMAT_DESCRIPTION, false, out uniformatDescription) == null) ParameterUtil.GetStringValueFromElementOrSymbol(element, "Assembly Description", out uniformatDescription); } IFCAnyHandle classification; if (!ExporterCacheManager.ClassificationCache.ClassificationHandles.TryGetValue(uniformatKeyString, out classification)) { classification = IFCInstanceExporter.CreateClassification(file, "http://www.csiorg.net/uniformat", "1998", null, uniformatKeyString); ExporterCacheManager.ClassificationCache.ClassificationHandles.Add(uniformatKeyString, classification); } InsertClassificationReference(exporterIFC, file, element, elemHnd, uniformatKeyString, uniformatCode, uniformatDescription, "http://www.csiorg.net/uniformat" ); }
override protected void Process(IFCAnyHandle item) { base.Process(item); IFCBooleanOperator? booleanOperator = IFCEnums.GetSafeEnumerationAttribute<IFCBooleanOperator>(item, "Operator"); if (booleanOperator.HasValue) BooleanOperator = booleanOperator.Value; IFCAnyHandle firstOperand = IFCImportHandleUtil.GetRequiredInstanceAttribute(item, "FirstOperand", true); FirstOperand = IFCBooleanOperand.ProcessIFCBooleanOperand(firstOperand); IFCAnyHandle secondOperand = IFCImportHandleUtil.GetRequiredInstanceAttribute(item, "SecondOperand", true); // We'll allow a solid to be created even if the second operand can't be properly handled. try { SecondOperand = IFCBooleanOperand.ProcessIFCBooleanOperand(secondOperand); } catch (Exception ex) { SecondOperand = null; Importer.TheLog.LogError(secondOperand.StepId, ex.Message, false); } }
/// <summary> /// Adds the IfcMaterialLayerSet handle to the dictionary. /// </summary> /// <param name="elementId"> /// The element elementId. /// </param> /// <param name="handle"> /// The IfcMaterialLayerSet handle. /// </param> public void Register(ElementId elementId, IFCAnyHandle handle) { if (m_ElementIdToMatLayerSetDictionary.ContainsKey(elementId)) return; m_ElementIdToMatLayerSetDictionary[elementId] = handle; }
override protected void Process(IFCAnyHandle item) { base.Process(item); SurfaceSide = IFCEnums.GetSafeEnumerationAttribute<IFCSurfaceSide>(item, "Side", IFCSurfaceSide.Both); HashSet<IFCAnyHandle> styles = IFCAnyHandleUtil.GetAggregateInstanceAttribute<HashSet<IFCAnyHandle>>(item, "Styles"); if (styles == null || styles.Count == 0) Importer.TheLog.LogError(item.StepId, "No style information found, ignoring.", true); foreach (IFCAnyHandle style in styles) { try { if (IFCAnyHandleUtil.IsSubTypeOf(style, IFCEntityType.IfcSurfaceStyleShading)) { if (ShadingStyle == null) ShadingStyle = IFCSurfaceStyleShading.ProcessIFCSurfaceStyleShading(style); else Importer.TheLog.LogWarning(item.StepId, "Duplicate IfcSurfaceStyleShading, ignoring.", false); } else Importer.TheLog.LogUnhandledSubTypeError(style, "IfcSurfaceStyleElementSelect", false); } catch (Exception ex) { Importer.TheLog.LogError(style.StepId, ex.Message, false); } } }
/// <summary> /// Processes IfcRelAssignsToGroup. /// </summary> /// <param name="isGroupedBy">The IfcRelAssignsToGroup handle.</param> void ProcessIFCRelAssignsToGroup(IFCAnyHandle isGroupedBy) { m_RelatedObjectType = ProcessIFCRelation.ProcessRelatedObjectType(isGroupedBy); // We will not process the related objects here, as that could cause infinite loops of partially processed items. // Instead, items will add themselves to their groups as they are processed. m_IFCRelatedObjects = new HashSet<IFCObjectDefinition>(); // ProcessIFCRelation.ProcessRelatedObjects(isGroupedBy); }
/// <summary> /// Validates the values to be set to IfcRoot. /// </summary> /// <param name="guid">The GUID.</param> /// <param name="ownerHistory">The owner history.</param> /// <param name="name">The name.</param> /// <param name="description">The description.</param> private static void ValidateRoot(string guid, IFCAnyHandle ownerHistory, string name, string description) { if (String.IsNullOrEmpty(guid)) throw new ArgumentException("Invalid guid.", "guid"); IFCAnyHandleUtil.ValidateSubTypeOf(ownerHistory, false, IFCEntityType.IfcOwnerHistory); }
/// <summary> /// Processes IfcSite attributes. /// </summary> /// <param name="ifcIFCSite">The IfcSite handle.</param> protected override void Process(IFCAnyHandle ifcIFCSite) { base.Process(ifcIFCSite); RefElevation = IFCImportHandleUtil.GetOptionalScaledLengthAttribute(ifcIFCSite, "RefElevation", 0.0); IList<int> refLatitudeList = IFCAnyHandleUtil.GetAggregateIntAttribute<List<int>>(ifcIFCSite, "RefLatitude"); IList<int> refLongitudeList = IFCAnyHandleUtil.GetAggregateIntAttribute<List<int>>(ifcIFCSite, "RefLongitude"); if (refLatitudeList != null) { m_RefLatitude = 0.0; int numLats = Math.Min(refLatitudeList.Count, 4); // Only support up to degress, minutes, seconds, and millionths of seconds. for (int ii = 0; ii < numLats; ii++) { m_RefLatitude += ((double)refLatitudeList[ii]) / GetLatLongScale(ii); } } if (refLongitudeList != null) { m_RefLongitude = 0.0; int numLongs = Math.Min(refLongitudeList.Count, 4); // Only support up to degress, minutes, seconds, and millionths of seconds. for (int ii = 0; ii < numLongs; ii++) { m_RefLongitude += ((double)refLongitudeList[ii]) / GetLatLongScale(ii); } } m_LandTitleNumber = IFCAnyHandleUtil.GetStringAttribute(ifcIFCSite, "LandTitleNumber"); }
/// <summary> /// Create an IFCProfile object from a handle of type IfcProfileDef. /// </summary> /// <param name="ifcProfileDef">The IFC handle.</param> /// <returns>The IFCProfileDef object.</returns> public static IFCProfile ProcessIFCProfile(IFCAnyHandle ifcProfileDef) { if (IFCAnyHandleUtil.IsNullOrHasNoValue(ifcProfileDef)) { IFCImportFile.TheLog.LogNullError(IFCEntityType.IfcProfileDef); return null; } IFCEntity profileDef; if (IFCImportFile.TheFile.EntityMap.TryGetValue(ifcProfileDef.StepId, out profileDef)) return (profileDef as IFCProfile); if (IFCAnyHandleUtil.IsSubTypeOf(ifcProfileDef, IFCEntityType.IfcCompositeProfileDef)) return IFCCompositeProfile.ProcessIFCCompositeProfile(ifcProfileDef); if (IFCAnyHandleUtil.IsSubTypeOf(ifcProfileDef, IFCEntityType.IfcDerivedProfileDef)) { IFCImportFile.TheLog.LogUnhandledSubTypeError(ifcProfileDef, IFCEntityType.IfcDerivedProfileDef, false); return null; } //if (IFCAnyHandleUtil.IsSubTypeOf(ifcProfileDef, IFCEntityType.IfcArbitraryOpenProfileDef)) //if (IFCAnyHandleUtil.IsSubTypeOf(ifcProfileDef, IFCEntityType.IfcArbitraryClosedProfileDef)) // IFC2x files don't have IfcParameterizedProfileDef, so we won't check the type. // If profileDef is the wrong entity type, it will fail in ProcessIFCParameterizedProfileDef. return IFCSimpleProfile.ProcessIFCSimpleProfile(ifcProfileDef); }
/// <summary> /// Creates uniformat classification. /// </summary> /// <param name="exporterIFC">The ExporterIFC.</param> /// <param name="file">The file.</param> /// <param name="element">The element.</param> /// <param name="elemHnd">The element handle.</param> public static void CreateUniformatClassification(ExporterIFC exporterIFC, IFCFile file, Element element, IFCAnyHandle elemHnd) { // Create Uniformat classification, if it is set. string uniformatCode = ""; if (ParameterUtil.GetStringValueFromElementOrSymbol(element, BuiltInParameter.UNIFORMAT_CODE, false, out uniformatCode) || ParameterUtil.GetStringValueFromElementOrSymbol(element, "Assembly Code", out uniformatCode)) { string uniformatDescription = ""; if (!ParameterUtil.GetStringValueFromElementOrSymbol(element, BuiltInParameter.UNIFORMAT_DESCRIPTION, false, out uniformatDescription)) ParameterUtil.GetStringValueFromElementOrSymbol(element, "Assembly Description", out uniformatDescription); IFCAnyHandle classification; if (!ExporterCacheManager.ClassificationCache.TryGetValue("UniFormat", out classification)) { classification = IFCInstanceExporter.CreateClassification(file, "http://www.csiorg.net/uniformat", "1998", null, "UniFormat"); ExporterCacheManager.ClassificationCache.Add("UniFormat", classification); } IFCAnyHandle classificationReference = IFCInstanceExporter.CreateClassificationReference(file, "http://www.csiorg.net/uniformat", uniformatCode, uniformatDescription, classification); HashSet<IFCAnyHandle> relatedObjects = new HashSet<IFCAnyHandle>(); relatedObjects.Add(elemHnd); IFCAnyHandle relAssociates = IFCInstanceExporter.CreateRelAssociatesClassification(file, ExporterIFCUtils.CreateGUID(), exporterIFC.GetOwnerHistoryHandle(), "UniFormatClassification", "", relatedObjects, classificationReference); } }
/// <summary> /// Finds all related objects in IfcRelAssigns. /// </summary> /// <param name="ifcRelAssigns">The IfcRelAssigns handle.</param> /// <returns>The related objects, or null if not found.</returns> static public ICollection<IFCObjectDefinition> ProcessRelatedObjects(IFCAnyHandle ifcRelAssignsOrAggregates) { try { ValidateIFCRelAssignsOrAggregates(ifcRelAssignsOrAggregates); } catch { //LOG: ERROR: Couldn't find valid IfcRelAssignsToGroup for IfcGroup. return null; } HashSet<IFCAnyHandle> relatedObjects = IFCAnyHandleUtil.GetAggregateInstanceAttribute <HashSet<IFCAnyHandle>>(ifcRelAssignsOrAggregates, "RelatedObjects"); // Receiving apps need to decide whether to post an error or not. if (relatedObjects == null) return null; ICollection<IFCObjectDefinition> relatedObjectSet = new HashSet<IFCObjectDefinition>(); foreach (IFCAnyHandle relatedObject in relatedObjects) { IFCObjectDefinition objectDefinition = IFCObjectDefinition.ProcessIFCObjectDefinition(relatedObject); if (objectDefinition != null) relatedObjectSet.Add(objectDefinition); } return relatedObjectSet; }
protected override void Process(IFCAnyHandle ifcCurve) { base.Process(ifcCurve); bool found = false; double radius = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(ifcCurve, "Radius", out found); if (!found) { Importer.TheLog.LogError(ifcCurve.StepId, "Cannot find the radius of this circle", false); return; } try { Curve = Arc.Create(Position.Origin, radius, 0, 2.0 * Math.PI, Position.BasisX, Position.BasisY); } catch (Exception ex) { if (ex.Message.Contains("too small")) { string lengthAsString = UnitFormatUtils.Format(IFCImportFile.TheFile.Document.GetUnits(), UnitType.UT_Length, radius, true, false); Importer.TheLog.LogError(Id, "Found a circle with radius of " + lengthAsString + ", ignoring.", false); Curve = null; } else Importer.TheLog.LogError(Id, ex.Message, false); Curve = null; } }
/// <summary> /// Processes an IFC element quantity. /// </summary> /// <param name="ifcElementQuantity">The IfcElementQuantity object.</param> protected override void Process(IFCAnyHandle ifcElementQuantity) { base.Process(ifcElementQuantity); MethodOfMeasurement = IFCImportHandleUtil.GetOptionalStringAttribute(ifcElementQuantity, "MethodOfMeasurement", null); HashSet<IFCAnyHandle> quantities = IFCAnyHandleUtil.GetAggregateInstanceAttribute<HashSet<IFCAnyHandle>>(ifcElementQuantity, "Quantities"); if (quantities != null) { m_IFCQuantities = new Dictionary<string, IFCPhysicalQuantity>(); foreach (IFCAnyHandle quantity in quantities) { IFCPhysicalQuantity ifcPhysicalQuantity = IFCPhysicalQuantity.ProcessIFCPhysicalQuantity(quantity); if (ifcPhysicalQuantity != null) m_IFCQuantities[ifcPhysicalQuantity.Name] = ifcPhysicalQuantity; } } else { Importer.TheLog.LogMissingRequiredAttributeError(ifcElementQuantity, "Quantities", false); } }
override protected void Process(IFCAnyHandle ifcSurface) { base.Process(ifcSurface); IFCAnyHandle position = IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcSurface, "Position", true); Position = IFCLocation.ProcessIFCAxis2Placement(position); }
/// <summary> /// Exports mullion. /// </summary> /// <param name="exporterIFC"> /// The ExporterIFC object. /// </param> /// <param name="mullion"> /// The mullion object. /// </param> /// <param name="geometryElement"> /// The geometry element. /// </param> /// <param name="localPlacement"> /// The local placement handle. /// </param> /// <param name="extraParams"> /// The extrusion creation data. /// </param> /// <param name="setter"> /// The IFCPlacementSetter. /// </param> /// <param name="productWrapper"> /// The IFCProductWrapper. /// </param> public static void Export(ExporterIFC exporterIFC, Mullion mullion, GeometryElement geometryElement, IFCAnyHandle localPlacement, IFCExtrusionCreationData extraParams, IFCPlacementSetter setter, IFCProductWrapper productWrapper) { IFCFile file = exporterIFC.GetFile(); ElementId catId = CategoryUtil.GetSafeCategoryId(mullion); IFCSolidMeshGeometryInfo solidMeshInfo = ExporterIFCUtils.GetSolidMeshGeometry(exporterIFC, geometryElement, Transform.Identity); IList<Solid> solids = solidMeshInfo.GetSolids(); IList<Mesh> polyMeshes = solidMeshInfo.GetMeshes(); bool tryToExportAsExtrusion = true; if (solids.Count != 1 || polyMeshes.Count != 0) tryToExportAsExtrusion = false; IFCAnyHandle shapeRep = BodyExporter.ExportBody(mullion.Document.Application, exporterIFC, catId, solids, polyMeshes, tryToExportAsExtrusion, extraParams); IList<IFCAnyHandle> shapeReps = new List<IFCAnyHandle>(); shapeReps.Add(shapeRep); IFCAnyHandle repHnd = file.CreateProductDefinitionShape(IFCLabel.Create(), IFCLabel.Create(), shapeReps); IFCLabel elemGUID = IFCLabel.CreateGUID(mullion); IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); IFCLabel elemObjectType = NamingUtil.CreateIFCObjectName(exporterIFC, mullion); IFCLabel elemId = NamingUtil.CreateIFCElementId(mullion); //IFCLabel elemType = IFCLabel.Create("MULLION"); IFCAnyHandle mullionHnd = file.CreateMember(elemGUID, ownerHistory, elemObjectType, IFCLabel.Create(), elemObjectType, localPlacement, repHnd, elemId); productWrapper.AddElement(mullionHnd, setter, extraParams, true); }
/// <summary> /// Gets the predefined type from the IfcObject, depending on the file version and entity type. /// </summary> /// <param name="ifcElementAssembly">The associated handle.</param> /// <returns>The predefined type, if any.</returns> protected override string GetPredefinedType(IFCAnyHandle ifcElementAssembly) { IFCElementAssemblyType predefinedType = IFCEnums.GetSafeEnumerationAttribute<IFCElementAssemblyType>(ifcElementAssembly, "PredefinedType", IFCElementAssemblyType.NotDefined); return predefinedType.ToString(); }
override protected void Process(IFCAnyHandle solid) { base.Process(solid); // We will not fail if the direction is not given, but instead assume it to be normal to the swept area. IFCAnyHandle direction = IFCImportHandleUtil.GetRequiredInstanceAttribute(solid, "ExtrudedDirection", false); if (direction != null) Direction = IFCPoint.ProcessNormalizedIFCDirection(direction); else Direction = XYZ.BasisZ; bool found = false; Depth = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(solid, "Depth", out found); if (found && Depth < 0.0) { // Reverse depth and orientation. if (Application.IsValidThickness(-Depth)) { Depth = -Depth; Direction = -Direction; Importer.TheLog.LogWarning(solid.StepId, "negative extrusion depth is invalid, reversing direction.", false); } } if (!found || !Application.IsValidThickness(Depth)) { string depthAsString = IFCUnitUtil.FormatLengthAsString(Depth); Importer.TheLog.LogError(solid.StepId, "extrusion depth of " + depthAsString + " is invalid, aborting.", true); } }
/// <summary> /// Processes an IFC property. /// </summary> /// <param name="ifcProperty">The property.</param> /// <returns>The IFCProperty object.</returns> public static IFCProperty ProcessIFCProperty(IFCAnyHandle ifcProperty) { if (IFCAnyHandleUtil.IsNullOrHasNoValue(ifcProperty)) { IFCImportFile.TheLog.LogNullError(IFCEntityType.IfcProperty); return null; } try { IFCEntity property; if (IFCImportFile.TheFile.EntityMap.TryGetValue(ifcProperty.StepId, out property)) return (property as IFCProperty); if (IFCAnyHandleUtil.IsSubTypeOf(ifcProperty, IFCEntityType.IfcComplexProperty)) return IFCComplexProperty.ProcessIFCComplexProperty(ifcProperty); if (IFCAnyHandleUtil.IsSubTypeOf(ifcProperty, IFCEntityType.IfcSimpleProperty)) return IFCSimpleProperty.ProcessIFCSimpleProperty(ifcProperty); } catch (Exception ex) { IFCImportFile.TheLog.LogError(ifcProperty.StepId, ex.Message, false); return null; } IFCImportFile.TheLog.LogUnhandledSubTypeError(ifcProperty, IFCEntityType.IfcProperty, false); return null; }
// This routine does no validity checking on the point, but does on attributes. private static XYZ ProcessIFCCartesianPointInternal(IFCAnyHandle point, IFCPointType expectedCoordinates) { IList<double> coordinates = IFCAnyHandleUtil.GetCoordinates(point); int numCoordinates = coordinates.Count; if (numCoordinates < 2) { //LOG: Warning: Expected at least 2 coordinates for IfcCartesianPoint, found {numCoordinates}. } else if (numCoordinates > 3) { //LOG: Warning: Expected at most 3 coordinates for IfcCartesianPoint, found {numCoordinates}. } if (expectedCoordinates != IFCPointType.DontCare) { if ((expectedCoordinates == IFCPointType.UVPoint) && (numCoordinates != 2)) { //LOG: Warning: Expected 2 coordinates for IfcCartesianPoint, found {numCoordinates}. if (numCoordinates > 2) numCoordinates = 2; } else if ((expectedCoordinates == IFCPointType.XYZPoint) && (numCoordinates != 3)) { //LOG: Warning: Expected 3 coordinates for IfcCartesianPoint, found {numCoordinates}. if (numCoordinates > 3) numCoordinates = 3; } } return ListToXYZ(coordinates); }
/// <summary> /// Processes IfcOpeningElement attributes. /// </summary> /// <param name="ifcOpeningElement">The IfcOpeningElement handle.</param> protected override void Process(IFCAnyHandle ifcOpeningElement) { base.Process(ifcOpeningElement); ICollection<IFCAnyHandle> hasFillings = IFCAnyHandleUtil.GetAggregateInstanceAttribute<List<IFCAnyHandle>>(ifcOpeningElement, "HasFillings"); if (hasFillings != null) { // Assume that there is only one filling for the opening, and take first found. foreach (IFCAnyHandle hasFilling in hasFillings) { IFCAnyHandle relatedFillingElement = IFCAnyHandleUtil.GetInstanceAttribute(hasFilling, "RelatedBuildingElement"); if (IFCAnyHandleUtil.IsNullOrHasNoValue(relatedFillingElement)) continue; IFCEntity filledByElement; IFCImportFile.TheFile.EntityMap.TryGetValue(relatedFillingElement.StepId, out filledByElement); if (filledByElement == null) FilledByElement = IFCElement.ProcessIFCElement(relatedFillingElement); else FilledByElement = filledByElement as IFCElement; FilledByElement.FillsOpening = this; break; } } }
/// <summary> /// Processes IfcSite attributes. /// </summary> /// <param name="ifcIFCSite">The IfcSite handle.</param> protected override void Process(IFCAnyHandle ifcIFCSite) { base.Process(ifcIFCSite); RefElevation = IFCImportHandleUtil.GetOptionalScaledLengthAttribute(ifcIFCSite, "RefElevation", 0.0); IList<int> refLatitudeList = IFCAnyHandleUtil.GetAggregateIntAttribute<List<int>>(ifcIFCSite, "RefLatitude"); IList<int> refLongitudeList = IFCAnyHandleUtil.GetAggregateIntAttribute<List<int>>(ifcIFCSite, "RefLongitude"); if (refLatitudeList != null) { m_RefLatitude = 0.0; double latLongScaler = 1.0; foreach (double latVal in refLatitudeList) { m_RefLatitude += ((double)latVal) / latLongScaler; latLongScaler *= 60.0; } } if (refLongitudeList != null) { m_RefLongitude = 0.0; double latLongScaler = 1.0; foreach (double longVal in refLongitudeList) { m_RefLongitude += ((double)longVal) / latLongScaler; latLongScaler *= 60.0; } } m_LandTitleNumber = IFCAnyHandleUtil.GetStringAttribute(ifcIFCSite, "LandTitleNumber"); }
/// <summary> /// Exports mullion. /// </summary> /// <param name="exporterIFC"> /// The ExporterIFC object. /// </param> /// <param name="mullion"> /// The mullion object. /// </param> /// <param name="geometryElement"> /// The geometry element. /// </param> /// <param name="localPlacement"> /// The local placement handle. /// </param> /// <param name="extraParams"> /// The extrusion creation data. /// </param> /// <param name="setter"> /// The IFCPlacementSetter. /// </param> /// <param name="productWrapper"> /// The IFCProductWrapper. /// </param> public static void Export(ExporterIFC exporterIFC, Mullion mullion, GeometryElement geometryElement, IFCAnyHandle localPlacement, IFCExtrusionCreationData extraParams, IFCPlacementSetter setter, IFCProductWrapper productWrapper) { IFCFile file = exporterIFC.GetFile(); ElementId catId = CategoryUtil.GetSafeCategoryId(mullion); BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true); IFCAnyHandle repHnd = RepresentationUtil.CreateBRepProductDefinitionShape(mullion.Document.Application, exporterIFC, mullion, catId, geometryElement, bodyExporterOptions, null, extraParams); if (IFCAnyHandleUtil.IsNullOrHasNoValue(repHnd)) { extraParams.ClearOpenings(); return; } string elemGUID = ExporterIFCUtils.CreateGUID(mullion); IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); string elemObjectType = NamingUtil.CreateIFCObjectName(exporterIFC, mullion); string elemId = NamingUtil.CreateIFCElementId(mullion); IFCAnyHandle mullionHnd = IFCInstanceExporter.CreateMember(file, elemGUID, ownerHistory, elemObjectType, null, elemObjectType, localPlacement, repHnd, elemId); productWrapper.AddElement(mullionHnd, setter, extraParams, LevelUtil.AssociateElementToLevel(mullion)); PropertyUtil.CreateInternalRevitPropertySets(exporterIFC, mullion, productWrapper); }
/// <summary> /// Processes IfcElementType attributes. /// </summary> /// <param name="ifcElementType">The IfcElementType handle.</param> protected override void Process(IFCAnyHandle ifcElementType) { base.Process(ifcElementType); ElementType = IFCAnyHandleUtil.GetStringAttribute(ifcElementType, "ElementType"); }
/// <summary> /// Update the local placements of the members of an assembly relative to the assembly. /// </summary> /// <param name="exporterIFC">The ExporerIFC.</param> /// <param name="assemblyPlacement">The assembly local placement handle.</param> /// <param name="elementPlacements">The member local placement handles.</param> public static void SetLocalPlacementsRelativeToAssembly(ExporterIFC exporterIFC, IFCAnyHandle assemblyPlacement, ICollection <IFCAnyHandle> elementPlacements) { foreach (IFCAnyHandle elementHandle in elementPlacements) { IFCAnyHandle elementPlacement = null; try { // The assembly may contain nested groups, that don't have an object placement. In this case, continue. elementPlacement = IFCAnyHandleUtil.GetObjectPlacement(elementHandle); } catch { continue; } Transform relTrf = ExporterIFCUtils.GetRelativeLocalPlacementOffsetTransform(assemblyPlacement, elementPlacement); Transform inverseTrf = relTrf.Inverse; IFCFile file = exporterIFC.GetFile(); IFCAnyHandle relLocalPlacement = ExporterUtil.CreateAxis2Placement3D(file, inverseTrf.Origin, inverseTrf.BasisZ, inverseTrf.BasisX); // NOTE: caution that old IFCAXIS2PLACEMENT3D may be unused as the new one replace it. // But we cannot delete it safely yet because we don't know if any handle is referencing it. GeometryUtil.SetRelativePlacement(elementPlacement, relLocalPlacement); GeometryUtil.SetPlacementRelTo(elementPlacement, assemblyPlacement); } }
protected IFCComplexProperty(IFCAnyHandle property) { Process(property); }
/// <summary> /// Exports a roof to IfcRoof. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="roof">The roof element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="productWrapper">The ProductWrapper.</param> /// <param name="exportRoofAsSingleGeometry">Export roof as single geometry.</param> public static void ExportRoof(ExporterIFC exporterIFC, Element roof, ref GeometryElement geometryElement, ProductWrapper productWrapper, bool exportRoofAsSingleGeometry = false) { if (roof == null || geometryElement == null) { return; } string ifcEnumType; IFCExportInfoPair roofExportType = ExporterUtil.GetProductExportType(exporterIFC, roof, out ifcEnumType); if (roofExportType.IsUnKnown) { roofExportType = new IFCExportInfoPair(IFCEntityType.IfcRoof, ""); } MaterialLayerSetInfo layersetInfo = new MaterialLayerSetInfo(exporterIFC, roof, productWrapper); IFCFile file = exporterIFC.GetFile(); Document doc = roof.Document; using (SubTransaction tempPartTransaction = new SubTransaction(doc)) { // For IFC4RV export, Roof will be split into its parts(temporarily) in order to export the roof by its parts ExporterUtil.CreateParts(roof, layersetInfo.MaterialIds.Count, ref geometryElement); bool exportByComponents = ExporterUtil.CanExportByComponentsOrParts(roof) == ExporterUtil.ExportPartAs.ShapeAspect; using (IFCTransaction tr = new IFCTransaction(file)) { // Check for containment override IFCAnyHandle overrideContainerHnd = null; ElementId overrideContainerId = ParameterUtil.OverrideContainmentParameter(exporterIFC, roof, out overrideContainerHnd); using (PlacementSetter placementSetter = PlacementSetter.Create(exporterIFC, roof, null, null, overrideContainerId, overrideContainerHnd)) { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { // If the roof is an in-place family, we will allow any arbitrary orientation. While this may result in some // in-place "cubes" exporting with the wrong direction, it is unlikely that an in-place family would be // used for this reason in the first place. ecData.PossibleExtrusionAxes = (roof is FamilyInstance) ? IFCExtrusionAxes.TryXYZ : IFCExtrusionAxes.TryZ; ecData.AreInnerRegionsOpenings = true; ecData.SetLocalPlacement(placementSetter.LocalPlacement); ElementId categoryId = CategoryUtil.GetSafeCategoryId(roof); BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow); BodyData bodyData = null; IFCAnyHandle prodRep = null; IList <IFCAnyHandle> representations = new List <IFCAnyHandle>(); IList <ElementId> materialIds = new List <ElementId>(); if (!exportByComponents) { prodRep = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, roof, categoryId, geometryElement, bodyExporterOptions, null, ecData, out bodyData); if (bodyData != null && bodyData.MaterialIds != null) { materialIds = bodyData.MaterialIds; } } else { prodRep = RepresentationUtil.CreateProductDefinitionShapeWithoutBodyRep(exporterIFC, roof, categoryId, geometryElement, representations); } if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodRep)) { ecData.ClearOpenings(); return; } bool exportSlab = ((ecData.ScaledLength > MathUtil.Eps() || exportByComponents) && roofExportType.ExportInstance == IFCEntityType.IfcRoof && !exportRoofAsSingleGeometry); string guid = GUIDUtil.CreateGUID(roof); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; IFCAnyHandle localPlacement = ecData.GetLocalPlacement(); IFCAnyHandle roofHnd = IFCInstanceExporter.CreateGenericIFCEntity( roofExportType, exporterIFC, roof, guid, ownerHistory, localPlacement, exportSlab ? null : prodRep); IFCAnyHandle typeHnd = ExporterUtil.CreateGenericTypeFromElement(roof, roofExportType, file, ownerHistory, roofExportType.ValidatedPredefinedType, productWrapper); ExporterCacheManager.TypeRelationsCache.Add(typeHnd, roofHnd); productWrapper.AddElement(roof, roofHnd, placementSetter.LevelInfo, ecData, true, roofExportType); if (!(roof is RoofBase)) { CategoryUtil.CreateMaterialAssociation(exporterIFC, roofHnd, materialIds); } if (exportByComponents && (exportSlab || exportRoofAsSingleGeometry)) { IFCAnyHandle hostShapeRepFromParts = PartExporter.ExportHostPartAsShapeAspects(exporterIFC, roof, prodRep, productWrapper, placementSetter, localPlacement, ElementId.InvalidElementId, layersetInfo, ecData); } Transform offsetTransform = (bodyData != null) ? bodyData.OffsetTransform : Transform.Identity; if (exportSlab) { string slabGUID = GUIDUtil.CreateSubElementGUID(roof, (int)IFCRoofSubElements.RoofSlabStart); IFCAnyHandle slabLocalPlacementHnd = ExporterUtil.CopyLocalPlacement(file, localPlacement); string slabName = IFCAnyHandleUtil.GetStringAttribute(roofHnd, "Name") + ":1"; IFCAnyHandle slabHnd = IFCInstanceExporter.CreateSlab(exporterIFC, roof, slabGUID, ownerHistory, slabLocalPlacementHnd, prodRep, slabRoofPredefinedType); IFCAnyHandleUtil.OverrideNameAttribute(slabHnd, slabName); OpeningUtil.CreateOpeningsIfNecessary(slabHnd, roof, ecData, offsetTransform, exporterIFC, slabLocalPlacementHnd, placementSetter, productWrapper); ExporterUtil.RelateObject(exporterIFC, roofHnd, slabHnd); IFCExportInfoPair slabRoofExportType = new IFCExportInfoPair(IFCEntityType.IfcSlab, slabRoofPredefinedType); productWrapper.AddElement(null, slabHnd, placementSetter.LevelInfo, ecData, false, slabRoofExportType); // Create type IFCAnyHandle slabRoofTypeHnd = ExporterUtil.CreateGenericTypeFromElement(roof, slabRoofExportType, exporterIFC.GetFile(), ownerHistory, slabRoofPredefinedType, productWrapper); ExporterCacheManager.TypeRelationsCache.Add(slabRoofTypeHnd, slabHnd); ExporterUtil.AddIntoComplexPropertyCache(slabHnd, layersetInfo); // For earlier than IFC4 version of IFC export, the material association will be done at the Roof host level with MaterialSetUsage // This one is only for IFC4 and above if ((roof is RoofBase) && !ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4) { if (layersetInfo != null && !IFCAnyHandleUtil.IsNullOrHasNoValue(layersetInfo.MaterialLayerSetHandle)) { CategoryUtil.CreateMaterialAssociation(slabHnd, layersetInfo.MaterialLayerSetHandle); } else if (bodyData != null) { CategoryUtil.CreateMaterialAssociation(exporterIFC, slabHnd, bodyData.MaterialIds); } } } else { OpeningUtil.CreateOpeningsIfNecessary(roofHnd, roof, ecData, offsetTransform, exporterIFC, localPlacement, placementSetter, productWrapper); // For earlier than IFC4 version of IFC export, the material association will be done at the Roof host level with MaterialSetUsage // This one is only for IFC4 and above if ((roof is RoofBase) && !ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4) { if (layersetInfo != null && !IFCAnyHandleUtil.IsNullOrHasNoValue(layersetInfo.MaterialLayerSetHandle)) { CategoryUtil.CreateMaterialAssociation(roofHnd, layersetInfo.MaterialLayerSetHandle); } else if (layersetInfo != null && layersetInfo.MaterialIds != null) { materialIds = layersetInfo.MaterialIds.Select(x => x.m_baseMatId).ToList(); CategoryUtil.CreateMaterialAssociation(exporterIFC, roofHnd, materialIds); } } } } tr.Commit(); } } } }
/// <summary> /// Exports a roof or floor as a container of multiple roof slabs. Returns the handle, if successful. /// </summary> /// <param name="exporterIFC">The exporter.</param> /// <param name="element">The roof or floor element.</param> /// <param name="geometry">The geometry of the element.</param> /// <param name="productWrapper">The product wrapper.</param> /// <returns>The roof handle.</returns> /// <remarks>For floors, if there is only one component, return null, as we do not want to create a container.</remarks> public static IFCAnyHandle ExportRoofOrFloorAsContainer(ExporterIFC exporterIFC, Element element, GeometryElement geometry, ProductWrapper productWrapper) { IFCFile file = exporterIFC.GetFile(); // We support ExtrusionRoofs, FootPrintRoofs, and Floors only. bool elementIsRoof = (element is ExtrusionRoof) || (element is FootPrintRoof); bool elementIsFloor = (element is Floor); if (!elementIsRoof && !elementIsFloor) { return(null); } string subSlabType = null; IFCExportInfoPair roofExportType = ExporterUtil.GetProductExportType(exporterIFC, element, out _); if (roofExportType.IsUnKnown) { IFCEntityType elementClassTypeEnum = elementIsFloor ? IFCEntityType.IfcSlab: IFCEntityType.IfcRoof; roofExportType = new IFCExportInfoPair(elementClassTypeEnum, ""); } else { if (elementIsFloor) { subSlabType = "FLOOR"; } else if (elementIsRoof) { subSlabType = "ROOF"; } } // Check the intended IFC entity or type name is in the exclude list specified in the UI if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(roofExportType.ExportType)) { return(null); } Document doc = element.Document; using (SubTransaction tempPartTransaction = new SubTransaction(doc)) { using (IFCTransaction transaction = new IFCTransaction(file)) { MaterialLayerSetInfo layersetInfo = new MaterialLayerSetInfo(exporterIFC, element, productWrapper); bool hasLayers = false; if (layersetInfo.MaterialIds.Count > 1) { hasLayers = true; } bool exportByComponents = ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView && hasLayers; // Check for containment override IFCAnyHandle overrideContainerHnd = null; ElementId overrideContainerId = ParameterUtil.OverrideContainmentParameter(exporterIFC, element, out overrideContainerHnd); // We want to delay creating entity handles until as late as possible, so that if we abort the IFC transaction, // we don't have to delete elements. This is both for performance reasons and to potentially extend the number // of projects that can be exported by reducing (a small amount) of waste. IList <HostObjectSubcomponentInfo> hostObjectSubcomponents = null; try { hostObjectSubcomponents = ExporterIFCUtils.ComputeSubcomponents(element as HostObject); } catch { return(null); } if (hostObjectSubcomponents == null) { return(null); } int numSubcomponents = hostObjectSubcomponents.Count; if (numSubcomponents == 0 || (elementIsFloor && numSubcomponents == 1)) { return(null); } using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element, null, null, overrideContainerId, overrideContainerHnd)) { IFCAnyHandle localPlacement = setter.LocalPlacement; IFCAnyHandle hostObjectHandle = null; try { using (IFCExtrusionCreationData extrusionCreationData = new IFCExtrusionCreationData()) { IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; extrusionCreationData.SetLocalPlacement(localPlacement); extrusionCreationData.ReuseLocalPlacement = true; using (TransformSetter trfSetter = TransformSetter.Create()) { IList <GeometryObject> geometryList = new List <GeometryObject>(); geometryList.Add(geometry); trfSetter.InitializeFromBoundingBox(exporterIFC, geometryList, extrusionCreationData); IFCAnyHandle prodRepHnd = null; string elementGUID = GUIDUtil.CreateGUID(element); hostObjectHandle = IFCInstanceExporter.CreateGenericIFCEntity( roofExportType, exporterIFC, element, elementGUID, ownerHistory, localPlacement, prodRepHnd); if (IFCAnyHandleUtil.IsNullOrHasNoValue(hostObjectHandle)) { return(null); } IList <IFCAnyHandle> elementHandles = new List <IFCAnyHandle>(); elementHandles.Add(hostObjectHandle); // If element is floor, then the profile curve loop of hostObjectSubComponent is computed from the top face of the floor // else if element is roof, then the profile curve loop is taken from the bottom face of the roof instead XYZ extrusionDir = elementIsFloor ? new XYZ(0, 0, -1) : new XYZ(0, 0, 1); ElementId catId = CategoryUtil.GetSafeCategoryId(element); IList <IFCAnyHandle> slabHandles = new List <IFCAnyHandle>(); IList <CurveLoop> hostObjectOpeningLoops = new List <CurveLoop>(); double maximumScaledDepth = 0.0; using (IFCExtrusionCreationData slabExtrusionCreationData = new IFCExtrusionCreationData()) { slabExtrusionCreationData.SetLocalPlacement(extrusionCreationData.GetLocalPlacement()); slabExtrusionCreationData.ReuseLocalPlacement = false; slabExtrusionCreationData.ForceOffset = true; int loopNum = 0; int subElementStart = elementIsRoof ? (int)IFCRoofSubElements.RoofSlabStart : (int)IFCSlabSubElements.SubSlabStart; foreach (HostObjectSubcomponentInfo hostObjectSubcomponent in hostObjectSubcomponents) { trfSetter.InitializeFromBoundingBox(exporterIFC, geometryList, slabExtrusionCreationData); Plane plane = hostObjectSubcomponent.GetPlane(); Transform lcs = GeometryUtil.CreateTransformFromPlane(plane); IList <CurveLoop> curveLoops = new List <CurveLoop>(); CurveLoop slabCurveLoop = hostObjectSubcomponent.GetCurveLoop(); curveLoops.Add(slabCurveLoop); double slope = Math.Abs(plane.Normal.Z); double scaledDepth = UnitUtil.ScaleLength(hostObjectSubcomponent.Depth); double scaledExtrusionDepth = scaledDepth * slope; IList <IFCAnyHandle> shapeReps = new List <IFCAnyHandle>(); IFCAnyHandle prodDefShape = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps); IFCAnyHandle contextOfItems = exporterIFC.Get3DContextHandle("Body"); string representationType = ShapeRepresentationType.SweptSolid.ToString(); // Create representation items based on the layers // Because in this case, the Roof components are not derived from Parts, but by "splitting" geometry part that can be extruded, // the creation of the Items for IFC4RV will be different by using "manual" split based on the layer thickness HashSet <IFCAnyHandle> bodyItems = new HashSet <IFCAnyHandle>(); if (!exportByComponents) { IFCAnyHandle itemShapeRep = ExtrusionExporter.CreateExtrudedSolidFromCurveLoop(exporterIFC, null, curveLoops, lcs, extrusionDir, scaledExtrusionDepth, false); if (IFCAnyHandleUtil.IsNullOrHasNoValue(itemShapeRep)) { productWrapper.ClearInternalHandleWrapperData(element); return(null); } ElementId matId = HostObjectExporter.GetFirstLayerMaterialId(element as HostObject); BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, element.Document, false, itemShapeRep, matId); bodyItems.Add(itemShapeRep); } else { List <MaterialLayerSetInfo.MaterialInfo> MaterialIds = layersetInfo.MaterialIds; ElementId typeElemId = element.GetTypeId(); // From CollectMaterialLayerSet() Roofs with no components are only allowed one material. It arbitrarily chooses the thickest material. // To be consistant with Roof(as Slab), we will reverse the order. IFCAnyHandle materialLayerSet = ExporterCacheManager.MaterialSetCache.FindLayerSet(typeElemId); bool materialHandleIsNotValid = IFCAnyHandleUtil.IsNullOrHasNoValue(materialLayerSet); if (IFCAnyHandleUtil.IsNullOrHasNoValue(materialLayerSet) || materialHandleIsNotValid) { MaterialIds.Reverse(); } double scaleProj = extrusionDir.DotProduct(plane.Normal); foreach (MaterialLayerSetInfo.MaterialInfo matLayerInfo in MaterialIds) { double itemExtrDepth = matLayerInfo.m_matWidth; double scaledItemExtrDepth = UnitUtil.ScaleLength(itemExtrDepth) * slope; IFCAnyHandle itemShapeRep = ExtrusionExporter.CreateExtrudedSolidFromCurveLoop(exporterIFC, null, curveLoops, lcs, extrusionDir, scaledItemExtrDepth, false); if (IFCAnyHandleUtil.IsNullOrHasNoValue(itemShapeRep)) { productWrapper.ClearInternalHandleWrapperData(element); return(null); } BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, element.Document, false, itemShapeRep, matLayerInfo.m_baseMatId); bodyItems.Add(itemShapeRep); RepresentationUtil.CreateRepForShapeAspect(exporterIFC, element, prodDefShape, representationType, matLayerInfo.m_layerName, itemShapeRep); XYZ offset = new XYZ(0, 0, itemExtrDepth / scaleProj); // offset is calculated as extent in the direction of extrusion lcs.Origin += offset; } } IFCAnyHandle shapeRep = RepresentationUtil.CreateSweptSolidRep(exporterIFC, element, catId, contextOfItems, bodyItems, null); shapeReps.Add(shapeRep); IFCAnyHandleUtil.SetAttribute(prodDefShape, "Representations", shapeReps); // We could replace the code below to just use the newer, and better, // GenerateIFCGuidFrom. The code below maintains compatibility with older // versions while generating a stable GUID for all slabs (in the unlikely // case that we have more than 255 of them). string slabGUID = (loopNum < 256) ? GUIDUtil.CreateSubElementGUID(element, subElementStart + loopNum) : GUIDUtil.GenerateIFCGuidFrom(element, "Slab: " + loopNum.ToString()); IFCAnyHandle slabPlacement = ExporterUtil.CreateLocalPlacement(file, slabExtrusionCreationData.GetLocalPlacement(), null); IFCAnyHandle slabHnd = IFCInstanceExporter.CreateSlab(exporterIFC, element, slabGUID, ownerHistory, slabPlacement, prodDefShape, subSlabType); IFCExportInfoPair exportType = new IFCExportInfoPair(IFCEntityType.IfcSlab, subSlabType); //slab quantities slabExtrusionCreationData.ScaledLength = scaledExtrusionDepth; slabExtrusionCreationData.ScaledArea = UnitUtil.ScaleArea(UnitUtil.ScaleArea(hostObjectSubcomponent.AreaOfCurveLoop)); slabExtrusionCreationData.ScaledOuterPerimeter = UnitUtil.ScaleLength(curveLoops[0].GetExactLength()); slabExtrusionCreationData.Slope = UnitUtil.ScaleAngle(MathUtil.SafeAcos(Math.Abs(slope))); IFCExportInfoPair slabRoofExportType = new IFCExportInfoPair(IFCEntityType.IfcSlab, subSlabType); productWrapper.AddElement(null, slabHnd, setter, slabExtrusionCreationData, false, slabRoofExportType); // Create type IFCAnyHandle slabRoofTypeHnd = ExporterUtil.CreateGenericTypeFromElement(element, slabRoofExportType, exporterIFC.GetFile(), ownerHistory, subSlabType, productWrapper); ExporterCacheManager.TypeRelationsCache.Add(slabRoofTypeHnd, slabHnd); elementHandles.Add(slabHnd); slabHandles.Add(slabHnd); hostObjectOpeningLoops.Add(slabCurveLoop); maximumScaledDepth = Math.Max(maximumScaledDepth, scaledDepth); loopNum++; ExporterUtil.AddIntoComplexPropertyCache(slabHnd, layersetInfo); // Create material association here if (layersetInfo != null && !IFCAnyHandleUtil.IsNullOrHasNoValue(layersetInfo.MaterialLayerSetHandle)) { CategoryUtil.CreateMaterialAssociation(slabHnd, layersetInfo.MaterialLayerSetHandle); } } } productWrapper.AddElement(element, hostObjectHandle, setter, extrusionCreationData, true, roofExportType); ExporterUtil.RelateObjects(exporterIFC, null, hostObjectHandle, slabHandles); OpeningUtil.AddOpeningsToElement(exporterIFC, elementHandles, hostObjectOpeningLoops, element, null, maximumScaledDepth, null, setter, localPlacement, productWrapper); transaction.Commit(); return(hostObjectHandle); } } } catch { // SOmething wrong with the above process, unable to create the extrusion data. Reset any internal handles that may have been partially created since they are not committed productWrapper.ClearInternalHandleWrapperData(element); return(null); } finally { exporterIFC.ClearFaceWithElementHandleMap(); } } } } }
/// <summary> /// Processes IfcBuilding attributes. /// </summary> /// <param name="ifcBuilding">The IfcBuilding handle.</param> protected override void Process(IFCAnyHandle ifcBuilding) { // TODO: process IfcBuilding specific data. base.Process(ifcBuilding); }
/// <summary> /// Constructs an IFCBuilding from the IfcBuilding handle. /// </summary> /// <param name="ifcBuilding">The IfcBuilding handle.</param> protected IFCBuilding(IFCAnyHandle ifcBuilding) { Process(ifcBuilding); }
/// <summary> /// Exports an element as an IFC assembly. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="element">The element.</param> /// <param name="productWrapper">The ProductWrapper.</param> /// <returns>True if exported successfully, false otherwise.</returns> public static bool ExportAssemblyInstanceElement(ExporterIFC exporterIFC, AssemblyInstance element, ProductWrapper productWrapper) { if (element == null) { return(false); } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { IFCAnyHandle assemblyInstanceHnd = null; string guid = GUIDUtil.CreateGUID(element); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; string name = NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element)); string description = NamingUtil.GetDescriptionOverride(element, null); string objectType = NamingUtil.GetObjectTypeOverride(element, exporterIFC.GetFamilyName()); IFCAnyHandle localPlacement = null; PlacementSetter placementSetter = null; IFCLevelInfo levelInfo = null; bool relateToLevel = true; string ifcEnumType; IFCExportType exportAs = ExporterUtil.GetExportType(exporterIFC, element, out ifcEnumType); if (exportAs == IFCExportType.IfcSystem) { assemblyInstanceHnd = IFCInstanceExporter.CreateSystem(file, guid, ownerHistory, name, description, objectType); // Create classification reference when System has classification filed name assigned to it ClassificationUtil.CreateClassification(exporterIFC, file, element, assemblyInstanceHnd); HashSet <IFCAnyHandle> relatedBuildings = new HashSet <IFCAnyHandle>(); relatedBuildings.Add(ExporterCacheManager.BuildingHandle); IFCAnyHandle relServicesBuildings = IFCInstanceExporter.CreateRelServicesBuildings(file, GUIDUtil.CreateGUID(), ExporterCacheManager.OwnerHistoryHandle, null, null, assemblyInstanceHnd, relatedBuildings); relateToLevel = false; // Already related to the building via IfcRelServicesBuildings. } else { using (placementSetter = PlacementSetter.Create(exporterIFC, element)) { string elementTag = NamingUtil.GetTagOverride(element, NamingUtil.CreateIFCElementId(element)); IFCAnyHandle representation = null; // We have limited support for exporting assemblies as other container types. localPlacement = placementSetter.LocalPlacement; levelInfo = placementSetter.LevelInfo; ifcEnumType = IFCValidateEntry.GetValidIFCType(element, ifcEnumType); switch (exportAs) { case IFCExportType.IfcCurtainWall: case IFCExportType.IfcCurtainWallType: assemblyInstanceHnd = IFCInstanceExporter.CreateCurtainWall(file, guid, ownerHistory, name, description, objectType, localPlacement, representation, elementTag); break; case IFCExportType.IfcRamp: string rampPredefinedType = RampExporter.GetIFCRampType(ifcEnumType); assemblyInstanceHnd = IFCInstanceExporter.CreateRamp(file, guid, ownerHistory, name, description, objectType, localPlacement, representation, elementTag, rampPredefinedType); break; case IFCExportType.IfcRoof: assemblyInstanceHnd = IFCInstanceExporter.CreateRoof(file, guid, ownerHistory, name, description, objectType, localPlacement, representation, elementTag, ifcEnumType); break; case IFCExportType.IfcStair: string stairPredefinedType = StairsExporter.GetIFCStairType(ifcEnumType); assemblyInstanceHnd = IFCInstanceExporter.CreateStair(file, guid, ownerHistory, name, description, objectType, localPlacement, representation, elementTag, stairPredefinedType); break; case IFCExportType.IfcWall: assemblyInstanceHnd = IFCInstanceExporter.CreateWall(file, guid, ownerHistory, name, description, objectType, localPlacement, representation, elementTag, ifcEnumType); break; default: IFCElementAssemblyType assemblyPredefinedType = GetPredefinedTypeFromObjectType(objectType); assemblyInstanceHnd = IFCInstanceExporter.CreateElementAssembly(file, guid, ownerHistory, name, description, objectType, localPlacement, representation, elementTag, IFCAssemblyPlace.NotDefined, assemblyPredefinedType); break; } } } if (assemblyInstanceHnd == null) { return(false); } // relateToLevel depends on how the AssemblyInstance is being mapped to IFC, above. productWrapper.AddElement(element, assemblyInstanceHnd, levelInfo, null, relateToLevel); ExporterCacheManager.AssemblyInstanceCache.RegisterAssemblyInstance(element.Id, assemblyInstanceHnd); tr.Commit(); return(true); } }
/// <summary> /// Constructs a SpaceOccupantInfo object. /// </summary> /// <param name="roomHandle">The room handle for this space occupant.</param> /// <param name="classificationReferences">The classification references for this space occupant.</param> /// <param name="psetHnd">The Pset_SpaceOccupant handle for this space occupant.</param> public SpaceOccupantInfo(IFCAnyHandle roomHandle, Dictionary <string, IFCAnyHandle> classificationReferences, IFCAnyHandle psetHnd) { RoomHandles.Add(roomHandle); ClassificationReferences = classificationReferences; SpaceOccupantProperySetHandle = psetHnd; }
protected IFCTriangulatedFaceSet(IFCAnyHandle item) { Process(item); }
protected IFCOrientedEdge(IFCAnyHandle ifcOrientedEdge) { Process(ifcOrientedEdge); }
protected IFCBSplineSurface(IFCAnyHandle bSplineSurface) { Process(bSplineSurface); }
protected IFCHalfSpaceSolid(IFCAnyHandle solid) { Process(solid); }
/// <summary> /// Constructs an IFCElementType from the IfcElementType handle. /// </summary> /// <param name="ifcElementType">The IfcElementType handle.</param> protected IFCElementType(IFCAnyHandle ifcElementType) { Process(ifcElementType); }
/// <summary> /// Exports curtain object as container. /// </summary> /// <param name="allSubElements"> /// Collection of elements contained in the host curtain element. /// </param> /// <param name="wallElement"> /// The curtain wall element. /// </param> /// <param name="exporterIFC"> /// The ExporterIFC object. /// </param> /// <param name="productWrapper"> /// The ProductWrapper. /// </param> public static void ExportCurtainObjectCommonAsContainer(ICollection <ElementId> allSubElements, Element wallElement, ExporterIFC exporterIFC, ProductWrapper origWrapper, PlacementSetter currSetter) { if (wallElement == null) { return; } string overrideCADLayer = null; ParameterUtil.GetStringValueFromElementOrSymbol(wallElement, "IFCCadLayer", out overrideCADLayer); using (ExporterStateManager.CADLayerOverrideSetter layerSetter = new ExporterStateManager.CADLayerOverrideSetter(overrideCADLayer)) { HashSet <ElementId> alreadyVisited = new HashSet <ElementId>(); // just in case. Options geomOptions = GeometryUtil.GetIFCExportGeometryOptions(); { foreach (ElementId subElemId in allSubElements) { using (ProductWrapper productWrapper = ProductWrapper.Create(origWrapper)) { Element subElem = wallElement.Document.GetElement(subElemId); if (subElem == null) { continue; } if (alreadyVisited.Contains(subElem.Id)) { continue; } alreadyVisited.Add(subElem.Id); // Respect element visibility settings. if (!ElementFilteringUtil.CanExportElement(exporterIFC, subElem, false) || !ElementFilteringUtil.IsElementVisible(subElem)) { continue; } GeometryElement geomElem = subElem.get_Geometry(geomOptions); if (geomElem == null) { continue; } try { if (subElem is FamilyInstance) { if (subElem is Mullion) { if (ExporterCacheManager.ExportOptionsCache.ExportAs2x2) { ProxyElementExporter.Export(exporterIFC, subElem, geomElem, productWrapper); } else { IFCAnyHandle currLocalPlacement = currSetter.LocalPlacement; MullionExporter.Export(exporterIFC, subElem as Mullion, geomElem, currLocalPlacement, currSetter, productWrapper); } } else { FamilyInstance subFamInst = subElem as FamilyInstance; string ifcEnumType; IFCExportType exportType = ExporterUtil.GetExportType(exporterIFC, subElem, out ifcEnumType); if (exportType == IFCExportType.IfcCurtainWall) { // By default, panels and mullions are set to the same category as their parent. In this case, // ask to get the exportType from the category id, since we don't want to inherit the parent class. ElementId catId = CategoryUtil.GetSafeCategoryId(subElem); exportType = ElementFilteringUtil.GetExportTypeFromCategoryId(catId, out ifcEnumType); } if (ExporterCacheManager.ExportOptionsCache.ExportAs2x2) { if ((exportType == IFCExportType.DontExport) || (exportType == IFCExportType.IfcPlateType) || (exportType == IFCExportType.IfcMemberType)) { exportType = IFCExportType.IfcBuildingElementProxyType; } } else { if (exportType == IFCExportType.DontExport) { ifcEnumType = "CURTAIN_PANEL"; exportType = IFCExportType.IfcPlateType; } } IFCAnyHandle currLocalPlacement = currSetter.LocalPlacement; using (IFCExtrusionCreationData extraParams = new IFCExtrusionCreationData()) { FamilyInstanceExporter.ExportFamilyInstanceAsMappedItem(exporterIFC, subFamInst, exportType, ifcEnumType, productWrapper, ElementId.InvalidElementId, null, currLocalPlacement); } } } else if (subElem is CurtainGridLine) { ProxyElementExporter.Export(exporterIFC, subElem, geomElem, productWrapper); } else if (subElem is Wall) { WallExporter.ExportWall(exporterIFC, subElem, null, geomElem, productWrapper); } } catch (Exception ex) { if (ExporterUtil.IsFatalException(wallElement.Document, ex)) { throw ex; } continue; } } } } } }
/// <summary> /// Exports mullion. /// </summary> /// <param name="exporterIFC"> /// The ExporterIFC object. /// </param> /// <param name="mullion"> /// The mullion object. /// </param> /// <param name="geometryElement"> /// The geometry element. /// </param> /// <param name="localPlacement"> /// The local placement handle. /// </param> /// <param name="setter"> /// The PlacementSetter. /// </param> /// <param name="productWrapper"> /// The ProductWrapper. /// </param> public static void Export(ExporterIFC exporterIFC, Mullion mullion, GeometryElement geometryElement, IFCAnyHandle localPlacement, PlacementSetter setter, ProductWrapper productWrapper) { IFCFile file = exporterIFC.GetFile(); using (PlacementSetter mullionSetter = PlacementSetter.Create(exporterIFC, mullion)) { using (IFCExtrusionCreationData extraParams = new IFCExtrusionCreationData()) { IFCAnyHandle mullionPlacement = mullionSetter.LocalPlacement; Transform relTrf = ExporterIFCUtils.GetRelativeLocalPlacementOffsetTransform(localPlacement, mullionPlacement); Transform inverseTrf = relTrf.Inverse; IFCAnyHandle mullionLocalPlacement = ExporterUtil.CreateLocalPlacement(file, localPlacement, inverseTrf.Origin, inverseTrf.BasisZ, inverseTrf.BasisX); extraParams.SetLocalPlacement(mullionLocalPlacement); Transform extrusionLCS = null; // Add a custom direction for trying to create an extrusion based on the base curve of the mullion, if it is a line and not an arc. Curve baseCurve = mullion.LocationCurve; if ((baseCurve != null) && (baseCurve is Line)) { // We won't use curveBounds and origin yet; just need the axis for now. IFCRange curveBounds; XYZ origin, mullionDirection; GeometryUtil.GetAxisAndRangeFromCurve(baseCurve, out curveBounds, out mullionDirection, out origin); // approx 1.0/sqrt(2.0) XYZ planeY = (Math.Abs(mullionDirection.Z) < 0.707) ? XYZ.BasisZ.CrossProduct(mullionDirection) : XYZ.BasisX.CrossProduct(mullionDirection); planeY.Normalize(); XYZ projDir = mullionDirection.CrossProduct(planeY); extrusionLCS = Transform.Identity; extrusionLCS.BasisX = mullionDirection; extrusionLCS.BasisY = planeY; extrusionLCS.BasisZ = projDir; extrusionLCS.Origin = origin; } ElementId catId = CategoryUtil.GetSafeCategoryId(mullion); BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow); bodyExporterOptions.ExtrusionLocalCoordinateSystem = extrusionLCS; IFCAnyHandle repHnd = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, mullion, catId, geometryElement, bodyExporterOptions, null, extraParams, true); if (IFCAnyHandleUtil.IsNullOrHasNoValue(repHnd)) { extraParams.ClearOpenings(); return; } string elemGUID = GUIDUtil.CreateGUID(mullion); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; string elemObjectType = NamingUtil.CreateIFCObjectName(exporterIFC, mullion); string name = NamingUtil.GetNameOverride(mullion, elemObjectType); string description = NamingUtil.GetDescriptionOverride(mullion, null); string objectType = NamingUtil.GetObjectTypeOverride(mullion, elemObjectType); string elemTag = NamingUtil.GetTagOverride(mullion, NamingUtil.CreateIFCElementId(mullion)); IFCAnyHandle mullionHnd = IFCInstanceExporter.CreateMember(file, elemGUID, ownerHistory, name, description, objectType, mullionLocalPlacement, repHnd, elemTag, "MULLION"); ExporterCacheManager.HandleToElementCache.Register(mullionHnd, mullion.Id); productWrapper.AddElement(mullion, mullionHnd, mullionSetter, extraParams, false); ElementId matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geometryElement, exporterIFC, mullion); CategoryUtil.CreateMaterialAssociation(exporterIFC, mullionHnd, matId); } } }
/// <summary> /// Exports curtain object as one Brep. /// </summary> /// <param name="allSubElements"> /// Collection of elements contained in the host curtain element. /// </param> /// <param name="wallElement"> /// The curtain wall element. /// </param> /// <param name="exporterIFC"> /// The ExporterIFC object. /// </param> /// <param name="setter"> /// The PlacementSetter object. /// </param> /// <param name="localPlacement"> /// The local placement handle. /// </param> /// <returns> /// The handle. /// </returns> public static IFCAnyHandle ExportCurtainObjectCommonAsOneBRep(ICollection <ElementId> allSubElements, Element wallElement, ExporterIFC exporterIFC, PlacementSetter setter, IFCAnyHandle localPlacement) { IFCAnyHandle prodDefRep = null; Document document = wallElement.Document; double eps = UnitUtil.ScaleLength(document.Application.VertexTolerance); IFCFile file = exporterIFC.GetFile(); IFCAnyHandle contextOfItems = exporterIFC.Get3DContextHandle("Body"); IFCGeometryInfo info = IFCGeometryInfo.CreateFaceGeometryInfo(eps); ISet <IFCAnyHandle> bodyItems = new HashSet <IFCAnyHandle>(); // Want to make sure we don't accidentally add a mullion or curtain line more than once. HashSet <ElementId> alreadyVisited = new HashSet <ElementId>(); bool useFallbackBREP = true; Options geomOptions = GeometryUtil.GetIFCExportGeometryOptions(); foreach (ElementId subElemId in allSubElements) { Element subElem = wallElement.Document.GetElement(subElemId); GeometryElement geomElem = subElem.get_Geometry(geomOptions); if (geomElem == null) { continue; } if (alreadyVisited.Contains(subElem.Id)) { continue; } alreadyVisited.Add(subElem.Id); // Export tessellated geometry when IFC4 Reference View is selected if (ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView) { BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(false, ExportOptionsCache.ExportTessellationLevel.ExtraLow); IFCAnyHandle triFaceSet = BodyExporter.ExportBodyAsTriangulatedFaceSet(exporterIFC, subElem, bodyExporterOptions, geomElem); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(triFaceSet)) { bodyItems.Add(triFaceSet); useFallbackBREP = false; // no need to do Brep since it is successful } } // Export AdvancedFace before use fallback BREP else if (ExporterCacheManager.ExportOptionsCache.ExportAs4DesignTransferView) { BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(false, ExportOptionsCache.ExportTessellationLevel.ExtraLow); IFCAnyHandle advancedBRep = BodyExporter.ExportBodyAsAdvancedBrep(exporterIFC, subElem, bodyExporterOptions, geomElem); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(advancedBRep)) { bodyItems.Add(advancedBRep); useFallbackBREP = false; // no need to do Brep since it is successful } } if (useFallbackBREP) { ExporterIFCUtils.CollectGeometryInfo(exporterIFC, info, geomElem, XYZ.Zero, false); HashSet <IFCAnyHandle> faces = new HashSet <IFCAnyHandle>(info.GetSurfaces()); IFCAnyHandle outer = IFCInstanceExporter.CreateClosedShell(file, faces); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(outer)) { bodyItems.Add(RepresentationUtil.CreateFacetedBRep(exporterIFC, document, outer, ElementId.InvalidElementId)); } } } if (bodyItems.Count == 0) { return(prodDefRep); } ElementId catId = CategoryUtil.GetSafeCategoryId(wallElement); IFCAnyHandle shapeRep; // Use tessellated geometry in Reference View if (ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView && !useFallbackBREP) { shapeRep = RepresentationUtil.CreateTessellatedRep(exporterIFC, wallElement, catId, contextOfItems, bodyItems, null); } else if (ExporterCacheManager.ExportOptionsCache.ExportAs4DesignTransferView && !useFallbackBREP) { shapeRep = RepresentationUtil.CreateAdvancedBRepRep(exporterIFC, wallElement, catId, contextOfItems, bodyItems, null); } else { shapeRep = RepresentationUtil.CreateBRepRep(exporterIFC, wallElement, catId, contextOfItems, bodyItems); } if (IFCAnyHandleUtil.IsNullOrHasNoValue(shapeRep)) { return(prodDefRep); } IList <IFCAnyHandle> shapeReps = new List <IFCAnyHandle>(); shapeReps.Add(shapeRep); IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, wallElement.get_Geometry(geomOptions), Transform.Identity); if (boundingBoxRep != null) { shapeReps.Add(boundingBoxRep); } prodDefRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps); return(prodDefRep); }
/// <summary> /// Exports curtain wall types to IfcCurtainWallType. /// </summary> /// <param name="exporterIFC">The exporter.</param> /// <param name="wrapper">The ProductWrapper class.</param> /// <param name="elementHandle">The element handle.</param> /// <param name="element">The element.</param> public static void ExportCurtainWallType(ExporterIFC exporterIFC, ProductWrapper wrapper, IFCAnyHandle elementHandle, Element element) { if (elementHandle == null || element == null) { return; } Document doc = element.Document; ElementId typeElemId = element.GetTypeId(); Element elementType = doc.GetElement(typeElemId); if (elementType == null) { return; } IFCAnyHandle wallType = null; if (ExporterCacheManager.WallTypeCache.TryGetValue(typeElemId, out wallType)) { ExporterCacheManager.TypeRelationsCache.Add(wallType, elementHandle); return; } string elemGUID = GUIDUtil.CreateGUID(elementType); string elemName = NamingUtil.GetNameOverride(elementType, NamingUtil.GetIFCName(elementType)); string elemDesc = NamingUtil.GetDescriptionOverride(elementType, null); string elemTag = NamingUtil.GetTagOverride(elementType, NamingUtil.CreateIFCElementId(elementType)); string elemApplicableOccurence = NamingUtil.GetOverrideStringValue(elementType, "IfcApplicableOccurence", null); string elemElementType = NamingUtil.GetOverrideStringValue(elementType, "IfcElementType", null); // Property sets will be set later. wallType = IFCInstanceExporter.CreateCurtainWallType(exporterIFC.GetFile(), elemGUID, ExporterCacheManager.OwnerHistoryHandle, elemName, elemDesc, elemApplicableOccurence, null, null, elemTag, elemElementType, (elemElementType != null) ? "USERDEFINED" : "NOTDEFINED"); wrapper.RegisterHandleWithElementType(elementType as ElementType, wallType, null); ExporterCacheManager.WallTypeCache[typeElemId] = wallType; ExporterCacheManager.TypeRelationsCache.Add(wallType, elementHandle); }
protected IFCIndexedPolygonalFace(IFCAnyHandle item) { Process(item); }
/// <summary> /// Export Curtain Walls and Roofs. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="allSubElements">Collection of elements contained in the host curtain element.</param> /// <param name="element">The element to be exported.</param> /// <param name="productWrapper">The ProductWrapper.</param> private static void ExportBase(ExporterIFC exporterIFC, ICollection <ElementId> allSubElements, Element element, ProductWrapper wrapper) { IFCFile file = exporterIFC.GetFile(); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; PlacementSetter setter = null; using (ProductWrapper curtainWallSubWrapper = ProductWrapper.Create(wrapper, false)) { try { Transform orientationTrf = Transform.Identity; IFCAnyHandle localPlacement = null; setter = PlacementSetter.Create(exporterIFC, element, null, orientationTrf); localPlacement = setter.LocalPlacement; string objectType = NamingUtil.CreateIFCObjectName(exporterIFC, element); IFCAnyHandle prodRepHnd = null; IFCAnyHandle elemHnd = null; string elemGUID = GUIDUtil.CreateGUID(element); string elemName = NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element)); string elemDesc = NamingUtil.GetDescriptionOverride(element, null); string elemType = NamingUtil.GetObjectTypeOverride(element, objectType); string elemTag = NamingUtil.GetTagOverride(element, NamingUtil.CreateIFCElementId(element)); if (element is Wall || element is CurtainSystem || IsLegacyCurtainElement(element)) { elemHnd = IFCInstanceExporter.CreateCurtainWall(file, elemGUID, ownerHistory, elemName, elemDesc, elemType, localPlacement, prodRepHnd, elemTag); } else if (element is RoofBase) { //need to convert the string to enum string ifcEnumType = ExporterUtil.GetIFCTypeFromExportTable(exporterIFC, element); ifcEnumType = IFCValidateEntry.GetValidIFCType(element, ifcEnumType); elemHnd = IFCInstanceExporter.CreateRoof(file, elemGUID, ownerHistory, elemName, elemDesc, elemType, localPlacement, prodRepHnd, elemTag, ifcEnumType); } else { return; } if (IFCAnyHandleUtil.IsNullOrHasNoValue(elemHnd)) { return; } wrapper.AddElement(element, elemHnd, setter, null, true); bool canExportCurtainWallAsContainer = CanExportCurtainWallAsContainer(allSubElements, element.Document); IFCAnyHandle rep = null; if (!canExportCurtainWallAsContainer) { rep = ExportCurtainObjectCommonAsOneBRep(allSubElements, element, exporterIFC, setter, localPlacement); if (IFCAnyHandleUtil.IsNullOrHasNoValue(rep)) { return; } } else { ExportCurtainObjectCommonAsContainer(allSubElements, element, exporterIFC, curtainWallSubWrapper, setter); } ICollection <IFCAnyHandle> relatedElementIds = curtainWallSubWrapper.GetAllObjects(); if (relatedElementIds.Count > 0) { string guid = GUIDUtil.CreateSubElementGUID(element, (int)IFCCurtainWallSubElements.RelAggregates); HashSet <IFCAnyHandle> relatedElementIdSet = new HashSet <IFCAnyHandle>(relatedElementIds); IFCInstanceExporter.CreateRelAggregates(file, guid, ownerHistory, null, null, elemHnd, relatedElementIdSet); } ExportCurtainWallType(exporterIFC, wrapper, elemHnd, element); SpaceBoundingElementUtil.RegisterSpaceBoundingElementHandle(exporterIFC, elemHnd, element.Id, ElementId.InvalidElementId); } finally { if (setter != null) { setter.Dispose(); } } } }
static void AddConnection(ExporterIFC exporterIFC, Connector connector, Connector connected, bool isBiDirectional, bool isElectricalDomain) { Element inElement = connector.Owner; Element outElement = connected.Owner; if (isElectricalDomain) { // We may get a connection back to the original element. Ignore it. if (inElement.Id == outElement.Id) { return; } // Check the outElement to see if it is a Wire; if so, get its connections and "skip" the wire. if (outElement is Wire) { if (m_ProcessedWires.Contains(outElement.Id)) { return; } m_ProcessedWires.Add(outElement.Id); try { ConnectorSet wireConnectorSet = MEPCache.GetConnectorsForWire(outElement as Wire); if (wireConnectorSet != null) { foreach (Connector connectedToWire in wireConnectorSet) { ProcessConnections(exporterIFC, connectedToWire, connector); } } } catch { } return; } } // Check if the connection already exist if (ConnectionExists(inElement.Id, outElement.Id)) { return; } if (isBiDirectional) { if (ConnectionExists(outElement.Id, inElement.Id)) { return; } } IFCAnyHandle inElementIFCHandle = ExporterCacheManager.MEPCache.Find(inElement.Id); IFCAnyHandle outElementIFCHandle = ExporterCacheManager.MEPCache.Find(outElement.Id); if (inElementIFCHandle == null || outElementIFCHandle == null || !IFCAnyHandleUtil.IsSubTypeOf(inElementIFCHandle, IFCEntityType.IfcElement) || !IFCAnyHandleUtil.IsSubTypeOf(outElementIFCHandle, IFCEntityType.IfcElement)) { return; } IFCFile ifcFile = exporterIFC.GetFile(); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; IFCAnyHandle portOut = null; IFCAnyHandle portIn = null; // ----------------------- In Port ---------------------- { string guid = GUIDUtil.CreateGUID(); IFCFlowDirection flowDir = (isBiDirectional) ? IFCFlowDirection.SourceAndSink : IFCFlowDirection.Sink; IFCAnyHandle localPlacement = CreateLocalPlacementForConnector(exporterIFC, connector, inElementIFCHandle, flowDir); string portName = "InPort_" + inElement.Id; string portType = "Flow"; // Assigned as Port.Description portIn = IFCInstanceExporter.CreateDistributionPort(ifcFile, guid, ownerHistory, portName, portType, null, localPlacement, null, flowDir); // Attach the port to the element guid = GUIDUtil.CreateGUID(); string connectionName = inElement.Id + "|" + guid; IFCAnyHandle connectorIn = IFCInstanceExporter.CreateRelConnectsPortToElement(ifcFile, guid, ownerHistory, connectionName, portType, portIn, inElementIFCHandle); } // ----------------------- Out Port---------------------- { string guid = GUIDUtil.CreateGUID(); IFCFlowDirection flowDir = (isBiDirectional) ? IFCFlowDirection.SourceAndSink : IFCFlowDirection.Source; IFCAnyHandle localPlacement = CreateLocalPlacementForConnector(exporterIFC, connected, outElementIFCHandle, flowDir); string portName = "OutPort_" + outElement.Id; string portType = "Flow"; // Assigned as Port.Description portOut = IFCInstanceExporter.CreateDistributionPort(ifcFile, guid, ownerHistory, portName, portType, null, localPlacement, null, flowDir); // Attach the port to the element guid = GUIDUtil.CreateGUID(); string connectionName = outElement.Id + "|" + guid; IFCAnyHandle connectorOut = IFCInstanceExporter.CreateRelConnectsPortToElement(ifcFile, guid, ownerHistory, connectionName, portType, portOut, outElementIFCHandle); } // ----------------------- Out Port -> In Port ---------------------- if (portOut != null && portIn != null) { Element elemToUse = (inElement.Id.IntegerValue < outElement.Id.IntegerValue) ? inElement : outElement; string guid = GUIDUtil.CreateGUID(); IFCAnyHandle realizingElement = null; string connectionName = ExporterUtil.GetGlobalId(portIn) + "|" + ExporterUtil.GetGlobalId(portOut); string connectionType = "Flow"; // Assigned as Description IFCInstanceExporter.CreateRelConnectsPorts(ifcFile, guid, ownerHistory, connectionName, connectionType, portIn, portOut, realizingElement); AddConnectionInternal(inElement.Id, outElement.Id); } // Add the handles to the connector system. HashSet <MEPSystem> systemList = new HashSet <MEPSystem>(); try { MEPSystem system = connector.MEPSystem; if (system != null) { systemList.Add(system); } } catch { } try { MEPSystem system = connected.MEPSystem; if (system != null) { systemList.Add(system); } } catch { } if (isElectricalDomain) { foreach (MEPSystem system in systemList) { ExporterCacheManager.SystemsCache.AddElectricalSystem(system.Id); ExporterCacheManager.SystemsCache.AddHandleToElectricalSystem(system.Id, inElementIFCHandle); ExporterCacheManager.SystemsCache.AddHandleToElectricalSystem(system.Id, outElementIFCHandle); ExporterCacheManager.SystemsCache.AddHandleToElectricalSystem(system.Id, portIn); ExporterCacheManager.SystemsCache.AddHandleToElectricalSystem(system.Id, portOut); } } else { foreach (MEPSystem system in systemList) { ExporterCacheManager.SystemsCache.AddHandleToBuiltInSystem(system, inElementIFCHandle); ExporterCacheManager.SystemsCache.AddHandleToBuiltInSystem(system, outElementIFCHandle); ExporterCacheManager.SystemsCache.AddHandleToBuiltInSystem(system, portIn); ExporterCacheManager.SystemsCache.AddHandleToBuiltInSystem(system, portOut); } } }
/// <summary> /// Processes IfcPropertySet attributes. /// </summary> /// <param name="ifcPropertySet">The IfcPropertySet handle.</param> protected IFCPropertySet(IFCAnyHandle ifcPropertySet) { Process(ifcPropertySet); }
/// <summary> /// Constructs an IFCElement from the IfcElement handle. /// </summary> /// <param name="ifcElement">The IfcElement handle.</param> protected IFCElement(IFCAnyHandle ifcElement) { Process(ifcElement); }
protected IFCStyledItem(IFCAnyHandle item) { Process(item); }
protected IFCCompositeCurve(IFCAnyHandle compositeCurve) { Process(compositeCurve); }
static IFCAnyHandle CreateLocalPlacementForConnector(ExporterIFC exporterIFC, Connector connector, IFCAnyHandle elementHandle, IFCFlowDirection flowDir) { try { IFCFile file = exporterIFC.GetFile(); IFCAnyHandle elementPlacement = IFCAnyHandleUtil.GetObjectPlacement(elementHandle); Transform origTrf = ExporterIFCUtils.GetUnscaledTransform(exporterIFC, elementPlacement); Transform connectorCoordinateSystem = connector.CoordinateSystem; if (flowDir == IFCFlowDirection.Sink) { // Reverse the direction of the connector. connectorCoordinateSystem.BasisX = -connectorCoordinateSystem.BasisX; connectorCoordinateSystem.BasisZ = -connectorCoordinateSystem.BasisZ; } Transform relTransform = origTrf.Inverse.Multiply(connectorCoordinateSystem); XYZ scaledOrigin = UnitUtil.ScaleLength(relTransform.Origin); IFCAnyHandle relLocalPlacement = ExporterUtil.CreateAxis2Placement3D(file, scaledOrigin, relTransform.BasisZ, relTransform.BasisX); return(IFCInstanceExporter.CreateLocalPlacement(file, elementPlacement, relLocalPlacement)); } catch { } return(null); }
protected IFCRepresentationItem(IFCAnyHandle item) { }
protected override void Process(IFCAnyHandle ifcCurve) { base.Process(ifcCurve); // We are going to attempt minor repairs for small but reasonable gaps between Line/Line and Line/Arc pairs. As such, we want to collect the // curves before we create the curve loop. IList <IFCAnyHandle> segments = IFCAnyHandleUtil.GetAggregateInstanceAttribute <List <IFCAnyHandle> >(ifcCurve, "Segments"); if (segments == null) { Importer.TheLog.LogError(Id, "Invalid IfcCompositeCurve with no segments.", true); } // need List<> so that we can AddRange later. List <Curve> curveSegments = new List <Curve>(); foreach (IFCAnyHandle segment in segments) { IList <Curve> currCurve = ProcessIFCCompositeCurveSegment(segment); if (currCurve != null && currCurve.Count != 0) { curveSegments.AddRange(currCurve); } } int numSegments = curveSegments.Count; if (numSegments == 0) { Importer.TheLog.LogError(Id, "Invalid IfcCompositeCurve with no segments.", true); } try { // We are going to try to reverse or tweak segments as necessary to make the CurveLoop. // For each curve, it is acceptable if it can be appended to the end of the existing loop, or prepended to its start, // possibly after reversing the curve, and possibly with some tweaking. // NOTE: we do not do any checks yet to repair the endpoints of the curveloop to make them closed. // NOTE: this is not expected to be perfect with dirty data, but is expected to not change already valid data. // curveLoopStartPoint and curveLoopEndPoint will change over time as we add new curves to the start or end of the CurveLoop. XYZ curveLoopStartPoint = curveSegments[0].GetEndPoint(0); XYZ curveLoopEndPoint = curveSegments[0].GetEndPoint(1); double vertexEps = IFCImportFile.TheFile.Document.Application.VertexTolerance; // This is intended to be "relatively large". The idea here is that the user would rather have the information presented // than thrown away because of a gap that is architecturally insignificant. double gapVertexEps = Math.Max(vertexEps, 0.01); // 1/100th of a foot, or 3.048 mm. double shortCurveTol = IFCImportFile.TheFile.Document.Application.ShortCurveTolerance; // canRepairFirst may change over time, as we may potentially add curves to the start of the CurveLoop. bool canRepairFirst = (curveSegments[0] is Line); for (int ii = 1; ii < numSegments; ii++) { XYZ nextStartPoint = curveSegments[ii].GetEndPoint(0); XYZ nextEndPoint = curveSegments[ii].GetEndPoint(1); // These will be set below. bool attachNextSegmentToEnd = false; bool reverseNextSegment = false; double minGap = 0.0; // Scoped to prevent distLoopEndPtToNextStartPt and others from being used later on. { // Find the minimum gap between the current curve segment and the existing curve loop. If it is too large, we will give up. double distLoopEndPtToNextStartPt = curveLoopEndPoint.DistanceTo(nextStartPoint); double distLoopEndPtToNextEndPt = curveLoopEndPoint.DistanceTo(nextEndPoint); double distLoopStartPtToNextEndPt = curveLoopStartPoint.DistanceTo(nextEndPoint); double distLoopStartPtToNextStartPt = curveLoopStartPoint.DistanceTo(nextStartPoint); // Determine the minimum gap between the two curves. If it is too large, we'll give up before trying anything. double minStartGap = Math.Min(distLoopStartPtToNextEndPt, distLoopStartPtToNextStartPt); double minEndGap = Math.Min(distLoopEndPtToNextStartPt, distLoopEndPtToNextEndPt); minGap = Math.Min(minStartGap, minEndGap); // If the minimum distance between the two curves is greater than gapVertexEps (which is the larger of our two tolerances), // we can't fix the issue. if (minGap > gapVertexEps) { string lengthAsString = UnitFormatUtils.Format(IFCImportFile.TheFile.Document.GetUnits(), UnitType.UT_Length, minGap, true, false); string maxGapAsString = UnitFormatUtils.Format(IFCImportFile.TheFile.Document.GetUnits(), UnitType.UT_Length, gapVertexEps, true, false); throw new InvalidOperationException("IfcCompositeCurve contains a gap of " + lengthAsString + " that is greater than the maximum gap size of " + maxGapAsString + " and cannot be repaired."); } // We have a possibility to add the segment. What we do depends on the gap distance. // If the current curve loop's closest end to the next segment is its end (vs. start) point, set attachNextSegmentToEnd to true. attachNextSegmentToEnd = (MathUtil.IsAlmostEqual(distLoopEndPtToNextStartPt, minGap)) || (MathUtil.IsAlmostEqual(distLoopEndPtToNextEndPt, minGap)); // We need to reverse the next segment if: // 1. We are attaching the next segment to the end of the curve loop, and the next segment's closest end to the current curve loop is its end (vs. start) point. // 2. We are attaching the next segment to the start of the curve loop, and the next segment's closest end to the current curve loop is its start (vs. end) point. reverseNextSegment = (MathUtil.IsAlmostEqual(distLoopEndPtToNextEndPt, minGap)) || (MathUtil.IsAlmostEqual(distLoopStartPtToNextStartPt, minGap)); } if (reverseNextSegment) { curveSegments[ii] = curveSegments[ii].CreateReversed(); MathUtil.Swap <XYZ>(ref nextStartPoint, ref nextEndPoint); } // If minGap is less than vertexEps, we won't need to do any repairing - just fix the orientation if necessary. if (minGap < vertexEps) { if (attachNextSegmentToEnd) { // Update the curve loop end point to be the end point of the next segment after potentially being reversed. curveLoopEndPoint = nextEndPoint; } else { canRepairFirst = curveSegments[ii] is Line; curveLoopStartPoint = nextStartPoint; // Update the curve loop start point to be the start point of the next segment, now at the beginning of the loop, // after potentially being reversed. Curve tmpCurve = curveSegments[ii]; curveSegments.RemoveAt(ii); curveSegments.Insert(0, tmpCurve); } continue; } // The gap is too big for CurveLoop, but smaller than our maximum tolerance - we will try to fix the gap by extending // one of the line segments around the gap. If the gap is between two Arcs, we will try to introduce a short // segment between them, as long as the gap is larger than the short curve tolerance. bool canRepairNext = curveSegments[ii] is Line; bool createdRepairLine = false; if (attachNextSegmentToEnd) { // Update the curve loop end point to be the end point of the next segment after potentially being reversed. XYZ originalCurveLoopEndPoint = curveLoopEndPoint; curveLoopEndPoint = nextEndPoint; if (canRepairNext) { curveSegments[ii] = RepairLineAndReport(Id, originalCurveLoopEndPoint, curveLoopEndPoint, minGap); } else if (curveSegments[ii - 1] is Line) // = canRepairCurrent, only used here. { curveSegments[ii - 1] = RepairLineAndReport(Id, curveSegments[ii - 1].GetEndPoint(0), curveSegments[ii].GetEndPoint(0), minGap); } else { // Can't add a line to fix a gap that is smaller than the short curve tolerance. // In the future, we may fix this gap by intersecting the two curves and extending one of them. if (minGap < shortCurveTol + MathUtil.Eps()) { Importer.TheLog.LogError(Id, "IfcCompositeCurve contains a gap between two non-linear segments that is too short to be repaired by a connecting segment.", true); } try { Line repairLine = Line.CreateBound(originalCurveLoopEndPoint, curveSegments[ii].GetEndPoint(0)); curveSegments.Insert(ii, repairLine); ii++; // Skip the repair line as we've already "added" it and the non-linear segment to our growing loop. numSegments++; createdRepairLine = true; } catch { Importer.TheLog.LogError(Id, "IfcCompositeCurve contains a gap between two non-linear segments that can't be fixed.", true); } } } else { XYZ originalCurveLoopStartPoint = curveLoopStartPoint; curveLoopStartPoint = nextStartPoint; if (canRepairNext) { curveSegments[ii] = RepairLineAndReport(Id, curveLoopStartPoint, originalCurveLoopStartPoint, minGap); } else if (canRepairFirst) { curveSegments[0] = RepairLineAndReport(Id, curveSegments[ii].GetEndPoint(1), curveSegments[0].GetEndPoint(1), minGap); } else { // Can't add a line to fix a gap that is smaller than the short curve tolerance. // In the future, we may fix this gap by intersecting the two curves and extending one of them. if (minGap < shortCurveTol + MathUtil.Eps()) { Importer.TheLog.LogError(Id, "IfcCompositeCurve contains a gap between two non-linear segments that is too short to be repaired by a connecting segment.", true); } Line repairLine = Line.CreateBound(curveSegments[ii].GetEndPoint(1), originalCurveLoopStartPoint); curveSegments.Insert(0, repairLine); ii++; // Skip the repair line as we've already "added" it and the non-linear curve to our growing loop. numSegments++; } // Either canRepairFirst was already true, or canRepairNext was true and we added it to the front of the loop, // or we added a short repair line to the front of the loop. In any of these cases, the front curve segement of the // loop is now a line segment. if (!canRepairFirst && !canRepairNext && !createdRepairLine) { Importer.TheLog.LogError(Id, "IfcCompositeCurve contains a gap between two non-linear segments that can't be fixed.", true); } canRepairFirst = true; // Move the curve to the front of the loop. Curve tmpCurve = curveSegments[ii]; curveSegments.RemoveAt(ii); curveSegments.Insert(0, tmpCurve); } } if (CurveLoop == null) { CurveLoop = new CurveLoop(); } foreach (Curve curveSegment in curveSegments) { CurveLoop.Append(curveSegment); } } catch (Exception ex) { Importer.TheLog.LogError(Id, ex.Message, true); } // Try to create the curve representation of this IfcCompositeCurve Curve = ConvertCurveLoopIntoSingleCurve(CurveLoop); }
protected IFCManifoldSolidBrep(IFCAnyHandle item) { Process(item); }
/// <summary> /// Processes IfcDoorLiningProperties attributes. /// </summary> /// <param name="ifcDoorLiningProperties">The IfcDoorLiningProperties handle.</param> protected IFCDoorLiningProperties(IFCAnyHandle ifcDoorLiningProperties) { Process(ifcDoorLiningProperties); }