/// <summary> /// Processes IfcRepresentationContext attributes. /// </summary> /// <param name="ifcRepresentationContext">The IfcRepresentationContext handle.</param> override protected void Process(IFCAnyHandle ifcRepresentationContext) { base.Process(ifcRepresentationContext); Identifier = IFCImportHandleUtil.GetOptionalStringAttribute(ifcRepresentationContext, "ContextIdentifier", null); Type = IFCImportHandleUtil.GetOptionalStringAttribute(ifcRepresentationContext, "ContextType", null); if (IFCAnyHandleUtil.IsSubTypeOf(ifcRepresentationContext, IFCEntityType.IfcGeometricRepresentationContext)) { bool found = false; CoordinateSpaceDimension = IFCImportHandleUtil.GetRequiredIntegerAttribute(ifcRepresentationContext, "CoordinateSpaceDimension", out found); if (!found) { CoordinateSpaceDimension = 3; // Don't throw, just set to default 3D. } Precision = IFCImportHandleUtil.GetOptionalScaledLengthAttribute(ifcRepresentationContext, "Precision", IFCImportFile.TheFile.Document.Application.VertexTolerance); IFCAnyHandle worldCoordinateSystem = IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcRepresentationContext, "WorldCoordinateSystem", false); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(worldCoordinateSystem)) { WorldCoordinateSystem = IFCLocation.ProcessIFCAxis2Placement(worldCoordinateSystem); } else { WorldCoordinateSystem = Transform.Identity; } // For IfcGeometricRepresentationSubContext, it seems as if try { IFCAnyHandle trueNorth = IFCImportHandleUtil.GetOptionalInstanceAttribute(ifcRepresentationContext, "TrueNorth"); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(trueNorth)) { TrueNorth = IFCPoint.ProcessNormalizedIFCDirection(trueNorth); } else { TrueNorth = XYZ.BasisZ; } } catch { TrueNorth = XYZ.BasisZ; } if (IFCImportFile.TheFile.SchemaVersion >= IFCSchemaVersion.IFC2x2 && IFCAnyHandleUtil.IsSubTypeOf(ifcRepresentationContext, IFCEntityType.IfcGeometricRepresentationSubContext)) { IFCAnyHandle parentContext = IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcRepresentationContext, "ParentContext", true); ParentContext = IFCRepresentationContext.ProcessIFCRepresentationContext(parentContext); TargetScale = IFCImportHandleUtil.GetOptionalPositiveRatioAttribute(ifcRepresentationContext, "TargetScale", 1.0); TargetView = IFCEnums.GetSafeEnumerationAttribute <IFCGeometricProjection>(ifcRepresentationContext, "TargetView", IFCGeometricProjection.NotDefined); UserDefinedTargetView = IFCImportHandleUtil.GetOptionalStringAttribute(ifcRepresentationContext, "UserDefinedTargetView", null); } } }
protected override void Process(IFCAnyHandle ifcMaterialLayer) { base.Process(ifcMaterialLayer); IFCAnyHandle ifcMaterial = IFCImportHandleUtil.GetOptionalInstanceAttribute(ifcMaterialLayer, "Material"); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(ifcMaterial)) { Material = IFCMaterial.ProcessIFCMaterial(ifcMaterial); } bool found = false; LayerThickness = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(ifcMaterialLayer, "LayerThickness", out found); if (!found) { return; } // GetOptionalLogicalAttribute defaults to Unknown. We want to default to false here. IsVentilated = IFCImportHandleUtil.GetOptionalLogicalAttribute(ifcMaterialLayer, "IsVentilated", out found); if (!found) { IsVentilated = IFCLogical.False; } }
/// <summary> /// Processes an IFC unit in the property. /// </summary> /// <param name="ifcSimpleProperty">The simple property.</param> /// <param name="simplePropertyHandle">The simple property handle.</param> static protected void ProcessIFCSimplePropertyUnit(IFCSimpleProperty ifcSimpleProperty, IFCAnyHandle simplePropertyHandle) { IFCAnyHandle ifcUnitHandle = IFCImportHandleUtil.GetOptionalInstanceAttribute(simplePropertyHandle, "Unit"); IFCUnit ifcUnit = (ifcUnitHandle != null) ? IFCUnit.ProcessIFCUnit(ifcUnitHandle) : null; if (ifcUnit == null) { if (ifcSimpleProperty.IFCPropertyValues.Count > 0) { IFCPropertyValue propertyValue = ifcSimpleProperty.IFCPropertyValues[0]; if (propertyValue != null && propertyValue.HasValue() && (propertyValue.Type == IFCDataPrimitiveType.Integer) || (propertyValue.Type == IFCDataPrimitiveType.Double)) { string unitTypeName; UnitType unitType = IFCDataUtil.GetUnitTypeFromData(propertyValue.Value, UnitType.UT_Undefined, out unitTypeName); if (unitType != UnitType.UT_Undefined) { ifcUnit = IFCImportFile.TheFile.IFCUnits.GetIFCProjectUnit(unitType); } else { Importer.TheLog.LogWarning(simplePropertyHandle.StepId, "Unhandled unit type: " + unitTypeName, true); } } } } ifcSimpleProperty.m_IFCUnit = ifcUnit; }
override protected void Process(IFCAnyHandle styledItem) { base.Process(styledItem); IFCAnyHandle item = IFCImportHandleUtil.GetOptionalInstanceAttribute(styledItem, "Item"); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(item)) { Item = IFCRepresentationItem.ProcessIFCRepresentationItem(item); } Name = IFCImportHandleUtil.GetOptionalStringAttribute(styledItem, "Name", null); List <IFCAnyHandle> styles = IFCAnyHandleUtil.GetAggregateInstanceAttribute <List <IFCAnyHandle> >(styledItem, "Styles"); if (styles == null || styles.Count == 0 || IFCAnyHandleUtil.IsNullOrHasNoValue(styles[0])) { Importer.TheLog.LogMissingRequiredAttributeError(styledItem, "Styles", true); } if (styles.Count > 1) { Importer.TheLog.LogWarning(styledItem.StepId, "Multiple presentation styles found for IfcStyledItem - using first.", false); } Styles = IFCPresentationStyleAssignment.ProcessIFCPresentationStyleAssignment(styles[0]); }
protected override void Process(IFCAnyHandle ifcMaterialProfile) { base.Process(ifcMaterialProfile); IFCAnyHandle ifcMaterial = IFCImportHandleUtil.GetOptionalInstanceAttribute(ifcMaterialProfile, "Material"); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(ifcMaterial)) { Material = IFCMaterial.ProcessIFCMaterial(ifcMaterial); } IFCAnyHandle profileHnd = IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcMaterialProfile, "Profile", true); if (profileHnd != null) { Profile = IFCProfileDef.ProcessIFCProfileDef(profileHnd); } Name = IFCImportHandleUtil.GetOptionalStringAttribute(ifcMaterialProfile, "Name", null); Description = IFCImportHandleUtil.GetOptionalStringAttribute(ifcMaterialProfile, "Description", null); double prio = IFCImportHandleUtil.GetOptionalRealAttribute(ifcMaterialProfile, "Priority", -1); if (prio >= 0) { Priority = prio; } Category = IFCImportHandleUtil.GetOptionalStringAttribute(ifcMaterialProfile, "Category", null); return; }
/// <summary> /// Processes an IFC physical simple quantity. /// </summary> /// <param name="ifcPhysicalQuantity">The IfcPhysicalSimpleQuantity object.</param> /// <returns>The IFCPhysicalSimpleQuantity object.</returns> override protected void Process(IFCAnyHandle ifcPhysicalSimpleQuantity) { base.Process(ifcPhysicalSimpleQuantity); IFCAnyHandle unit = IFCImportHandleUtil.GetOptionalInstanceAttribute(ifcPhysicalSimpleQuantity, "Unit"); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(unit)) { IFCUnit = IFCUnit.ProcessIFCUnit(unit); } // Process subtypes of IfcPhysicalSimpleQuantity here. string attributeName = ifcPhysicalSimpleQuantity.TypeName.Substring(11) + "Value"; Value = ifcPhysicalSimpleQuantity.GetAttribute(attributeName); BaseUnitType = IFCDataUtil.GetUnitTypeFromData(Value, UnitType.UT_Undefined); if (BaseUnitType == UnitType.UT_Undefined) { // Determine it from the attributeName. if (string.Compare(attributeName, "LengthValue", true) == 0) { BaseUnitType = UnitType.UT_Length; } else if (string.Compare(attributeName, "AreaValue", true) == 0) { BaseUnitType = UnitType.UT_Area; } else if (string.Compare(attributeName, "VolumeValue", true) == 0) { BaseUnitType = UnitType.UT_Volume; } else if (string.Compare(attributeName, "CountValue", true) == 0) { BaseUnitType = UnitType.UT_Number; } else if (string.Compare(attributeName, "WeightValue", true) == 0) { BaseUnitType = UnitType.UT_Mass; } else if (string.Compare(attributeName, "TimeValue", true) == 0) { BaseUnitType = UnitType.UT_Number; // No time unit type in Revit. } else { Importer.TheLog.LogWarning(Id, "Can't determine unit type for IfcPhysicalSimpleQuantity of type: " + attributeName, true); BaseUnitType = UnitType.UT_Number; } } if (IFCUnit == null) { IFCUnit = IFCImportFile.TheFile.IFCUnits.GetIFCProjectUnit(BaseUnitType); } }
/// <summary> /// Processes an IFCDoorWindowPropertyBase entity. /// </summary> /// <param name="ifcDoorWindowPropertyBase">The ifcDoorWindowPropertyBase handle.</param> protected override void Process(IFCAnyHandle ifcDoorWindowPropertyBase) { base.Process(ifcDoorWindowPropertyBase); IFCAnyHandle shapeAspectStyle = IFCImportHandleUtil.GetOptionalInstanceAttribute(ifcDoorWindowPropertyBase, "ShapeAspectStyle"); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(shapeAspectStyle)) { Importer.TheLog.LogError(Id, "ShapeAspectStyle unsupported.", false); } }
/// <summary> /// Processes IfcProduct attributes. /// </summary> /// <param name="ifcProduct">The IfcProduct handle.</param> protected override void Process(IFCAnyHandle ifcProduct) { base.Process(ifcProduct); ProcessObjectPlacement(ifcProduct); IFCAnyHandle ifcProductRepresentation = IFCImportHandleUtil.GetOptionalInstanceAttribute(ifcProduct, "Representation"); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(ifcProductRepresentation)) { ProductRepresentation = IFCProductRepresentation.ProcessIFCProductRepresentation(ifcProductRepresentation); } }
override protected void Process(IFCAnyHandle styledItem) { base.Process(styledItem); IFCAnyHandle item = IFCImportHandleUtil.GetOptionalInstanceAttribute(styledItem, "Item"); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(item)) { Item = IFCRepresentationItem.ProcessIFCRepresentationItem(item); } Name = IFCImportHandleUtil.GetOptionalStringAttribute(styledItem, "Name", null); List <IFCAnyHandle> styles = IFCAnyHandleUtil.GetAggregateInstanceAttribute <List <IFCAnyHandle> >(styledItem, "Styles"); if (styles == null || styles.Count == 0) { Importer.TheLog.LogMissingRequiredAttributeError(styledItem, "Styles", true); } foreach (IFCAnyHandle style in styles) { if (IFCAnyHandleUtil.IsNullOrHasNoValue(style)) { continue; } if (IFCImportFile.TheFile.SchemaVersionAtLeast(IFCSchemaVersion.IFC4Obsolete) && IFCAnyHandleUtil.IsValidSubTypeOf(style, IFCEntityType.IfcPresentationStyle)) { Styles.Add(IFCPresentationStyle.ProcessIFCPresentationStyle(style)); } else { if (Styles.Count != 0) { Importer.TheLog.LogWarning(styledItem.StepId, "Multiple presentation styles found for IfcStyledItem - using first.", false); continue; } IFCPresentationStyleAssignment presentationStyleAssignment = IFCPresentationStyleAssignment.ProcessIFCPresentationStyleAssignment(style); if (presentationStyleAssignment != null && presentationStyleAssignment.Styles != null) { Styles.AddRange(presentationStyleAssignment.Styles); } } } }
/// <summary> /// Processes IfcProduct attributes. /// </summary> /// <param name="ifcProduct">The IfcProduct handle.</param> protected override void Process(IFCAnyHandle ifcProduct) { // We are going to process the IfcObjectPlacement before we do the base Process call. The reason for this is that we'd like to // process the IfcSite object placement before any of its children, so that the RelativeToSite can be properly set. // If this becomes an issue, we can instead move this to after the base.Process, and calculate RelativeToSite as a post-process step. ProcessObjectPlacement(ifcProduct); base.Process(ifcProduct); IFCAnyHandle ifcProductRepresentation = IFCImportHandleUtil.GetOptionalInstanceAttribute(ifcProduct, "Representation"); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(ifcProductRepresentation)) { ProductRepresentation = IFCProductRepresentation.ProcessIFCProductRepresentation(ifcProductRepresentation); } }
override protected void Process(IFCAnyHandle ifcSurface) { base.Process(ifcSurface); IFCAnyHandle sweptCurve = IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcSurface, "SweptCurve", true); SweptCurve = IFCProfile.ProcessIFCProfile(sweptCurve); IFCAnyHandle position = IFCImportHandleUtil.GetOptionalInstanceAttribute(ifcSurface, "Position"); if (IFCAnyHandleUtil.IsNullOrHasNoValue(position)) { Position = Transform.Identity; } else { Position = IFCLocation.ProcessIFCAxis2Placement(position); } }
protected override void Process(IFCAnyHandle ifcMaterialProfileSet) { base.Process(ifcMaterialProfileSet); IList <IFCAnyHandle> ifcMaterialProfiles = IFCAnyHandleUtil.GetAggregateInstanceAttribute <List <IFCAnyHandle> >(ifcMaterialProfileSet, "MaterialProfiles"); if (ifcMaterialProfiles == null) { Importer.TheLog.LogError(ifcMaterialProfileSet.Id, "Expected at least 1 MaterialProfile, found none.", false); return; } foreach (IFCAnyHandle ifcMaterialProfile in ifcMaterialProfiles) { IFCMaterialProfile materialProfile = null; if (IFCAnyHandleUtil.IsTypeOf(ifcMaterialProfile, IFCEntityType.IfcMaterialProfileWithOffsets)) { materialProfile = IFCMaterialProfileWithOffsets.ProcessIFCMaterialProfileWithOffsets(ifcMaterialProfile); } else { materialProfile = IFCMaterialProfile.ProcessIFCMaterialProfile(ifcMaterialProfile); } if (materialProfile != null) { MaterialProfileSet.Add(materialProfile); } } Name = IFCImportHandleUtil.GetOptionalStringAttribute(ifcMaterialProfileSet, "Name", null); Description = IFCImportHandleUtil.GetOptionalStringAttribute(ifcMaterialProfileSet, "Description", null); IFCAnyHandle compositeProfileHnd = IFCImportHandleUtil.GetOptionalInstanceAttribute(ifcMaterialProfileSet, "CompositeProfile"); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(compositeProfileHnd)) { CompositeProfile = IFCCompositeProfile.ProcessIFCCompositeProfile(compositeProfileHnd); } }
protected override void Process(IFCAnyHandle ifcEdge) { base.Process(ifcEdge); // The ODA toolkit doesn't support derived attributes. As such, we will // let IfcOrientedEdge compute them. IFCAnyHandle edgeStart = IFCImportHandleUtil.GetOptionalInstanceAttribute(ifcEdge, "EdgeStart"); if (IFCAnyHandleUtil.IsNullOrHasNoValue(edgeStart)) { if (!(this is IFCOrientedEdge)) { Importer.TheLog.LogError(ifcEdge.StepId, "Cannot find the starting vertex", true); return; } } else { EdgeStart = IFCVertex.ProcessIFCVertex(edgeStart); } IFCAnyHandle edgeEnd = IFCImportHandleUtil.GetOptionalInstanceAttribute(ifcEdge, "EdgeEnd"); if (IFCAnyHandleUtil.IsNullOrHasNoValue(edgeEnd)) { if (!(this is IFCOrientedEdge)) { Importer.TheLog.LogError(ifcEdge.StepId, "Cannot find the ending vertex", true); return; } } else { EdgeEnd = IFCVertex.ProcessIFCVertex(edgeEnd); } }
override protected void Process(IFCAnyHandle item) { base.Process(item); IFCAnyHandle localOrigin = IFCImportHandleUtil.GetRequiredInstanceAttribute(item, "LocalOrigin", false); XYZ origin = null; if (localOrigin != null) { origin = IFCPoint.ProcessScaledLengthIFCCartesianPoint(localOrigin); } else { origin = XYZ.Zero; } IFCAnyHandle axis1 = IFCImportHandleUtil.GetOptionalInstanceAttribute(item, "Axis1"); XYZ xAxis = null; if (axis1 != null) { xAxis = IFCPoint.ProcessNormalizedIFCDirection(axis1); } IFCAnyHandle axis2 = IFCImportHandleUtil.GetOptionalInstanceAttribute(item, "Axis2"); XYZ yAxis = null; if (axis2 != null) { yAxis = IFCPoint.ProcessNormalizedIFCDirection(axis2); } Scale = IFCImportHandleUtil.GetOptionalRealAttribute(item, "Scale", 1.0); XYZ zAxis = null; if (IFCAnyHandleUtil.IsSubTypeOf(item, IFCEntityType.IfcCartesianTransformationOperator2DnonUniform)) { ScaleY = IFCImportHandleUtil.GetOptionalRealAttribute(item, "Scale2", Scale); } else if (IFCAnyHandleUtil.IsSubTypeOf(item, IFCEntityType.IfcCartesianTransformationOperator3D)) { IFCAnyHandle axis3 = IFCImportHandleUtil.GetOptionalInstanceAttribute(item, "Axis3"); if (axis3 != null) { zAxis = IFCPoint.ProcessNormalizedIFCDirection(axis3); } if (IFCAnyHandleUtil.IsSubTypeOf(item, IFCEntityType.IfcCartesianTransformationOperator3DnonUniform)) { ScaleY = IFCImportHandleUtil.GetOptionalRealAttribute(item, "Scale2", Scale); ScaleZ = IFCImportHandleUtil.GetOptionalRealAttribute(item, "Scale3", Scale); } } // Set the axes based on what is specified. // If all three axes are set, ensure they are truly orthogonal. // If two axes are set, ensure they are orthogonal and set the 3rd axis to be the cross product. // If one axis is set, arbitrarily set the next axis to be the basis vector which // If no axes are set, use identity transform. if (xAxis == null) { if (yAxis == null) { if (zAxis == null) { xAxis = XYZ.BasisX; yAxis = XYZ.BasisY; zAxis = XYZ.BasisZ; } } else if (zAxis == null) { // Special case - Y axis is in XY plane. if (MathUtil.IsAlmostZero(yAxis[2])) { xAxis = new XYZ(yAxis[1], -yAxis[0], 0.0); zAxis = XYZ.BasisZ; } else { throw new InvalidOperationException("#" + item.StepId + ": IfcCartesianTransformOperator has only y axis defined, ignoring."); } } else { xAxis = yAxis.CrossProduct(zAxis); } } else if (yAxis == null) { if (zAxis == null) { // Special case - X axis is in XY plane. if (MathUtil.IsAlmostZero(xAxis[2])) { yAxis = new XYZ(xAxis[1], -xAxis[0], 0.0); zAxis = XYZ.BasisZ; } else { throw new InvalidOperationException("#" + item.StepId + ": IfcCartesianTransformOperator has only x axis defined, ignoring."); } } else { yAxis = zAxis.CrossProduct(xAxis); } } else if (zAxis == null) { zAxis = xAxis.CrossProduct(yAxis); } // Make sure that the axes are really orthogonal. if (!MathUtil.IsAlmostZero(xAxis.DotProduct(zAxis))) { zAxis = xAxis.CrossProduct(yAxis); } if (!MathUtil.IsAlmostZero(xAxis.DotProduct(yAxis))) { yAxis = zAxis.CrossProduct(xAxis); } Transform = Transform.CreateTranslation(origin); Transform.set_Basis(0, xAxis); Transform.set_Basis(1, yAxis); Transform.set_Basis(2, zAxis); }
override protected void Process(IFCAnyHandle item) { base.Process(item); IFCAnyHandle localOrigin = IFCImportHandleUtil.GetRequiredInstanceAttribute(item, "LocalOrigin", false); XYZ origin = null; if (localOrigin != null) { origin = IFCPoint.ProcessScaledLengthIFCCartesianPoint(localOrigin); } else { origin = XYZ.Zero; } IFCAnyHandle axis1 = IFCImportHandleUtil.GetOptionalInstanceAttribute(item, "Axis1"); XYZ xAxis = null; if (axis1 != null) { xAxis = IFCPoint.ProcessNormalizedIFCDirection(axis1); } IFCAnyHandle axis2 = IFCImportHandleUtil.GetOptionalInstanceAttribute(item, "Axis2"); XYZ yAxis = null; if (axis2 != null) { yAxis = IFCPoint.ProcessNormalizedIFCDirection(axis2); } Scale = IFCImportHandleUtil.GetOptionalRealAttribute(item, "Scale", 1.0); XYZ zAxis = null; // Assume that the dimensionality of the IfcCartesianTransformationOperator is 2, unless determined otherwise below. int dim = 2; if (IFCAnyHandleUtil.IsSubTypeOf(item, IFCEntityType.IfcCartesianTransformationOperator2DnonUniform)) { ScaleY = IFCImportHandleUtil.GetOptionalRealAttribute(item, "Scale2", Scale); } else if (IFCAnyHandleUtil.IsSubTypeOf(item, IFCEntityType.IfcCartesianTransformationOperator3D)) { dim = 3; IFCAnyHandle axis3 = IFCImportHandleUtil.GetOptionalInstanceAttribute(item, "Axis3"); if (axis3 != null) { zAxis = IFCPoint.ProcessNormalizedIFCDirection(axis3); } if (IFCAnyHandleUtil.IsSubTypeOf(item, IFCEntityType.IfcCartesianTransformationOperator3DnonUniform)) { ScaleY = IFCImportHandleUtil.GetOptionalRealAttribute(item, "Scale2", Scale); ScaleZ = IFCImportHandleUtil.GetOptionalRealAttribute(item, "Scale3", Scale); } } // Set the axes based on what is specified. Transform = CreateTransformUsingIfcBaseAxisCalculation(xAxis, yAxis, zAxis, origin, dim, Id); }
/// <summary> /// Processes IfcProject attributes. /// </summary> /// <param name="ifcProjectHandle">The IfcProject handle.</param> protected override void Process(IFCAnyHandle ifcProjectHandle) { IFCAnyHandle unitsInContext = IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcProjectHandle, "UnitsInContext", false); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(unitsInContext)) { IList <IFCAnyHandle> units = IFCAnyHandleUtil.GetAggregateInstanceAttribute <List <IFCAnyHandle> >(unitsInContext, "Units"); if (units != null) { m_UnitsInContext = new HashSet <IFCUnit>(); foreach (IFCAnyHandle unit in units) { IFCUnit ifcUnit = IFCImportFile.TheFile.IFCUnits.ProcessIFCProjectUnit(unit); if (!IFCUnit.IsNullOrInvalid(ifcUnit)) { m_UnitsInContext.Add(ifcUnit); } } } else { Importer.TheLog.LogMissingRequiredAttributeError(unitsInContext, "Units", false); } } var application = IFCImportFile.TheFile.Document.Application; var projectUnits = IFCImportFile.TheFile.IFCUnits.GetIFCProjectUnit(SpecTypeId.Length); IFCImportFile.TheFile.VertexTolerance = application.VertexTolerance; IFCImportFile.TheFile.ShortCurveTolerance = application.ShortCurveTolerance; Importer.TheProcessor.PostProcessProject(projectUnits?.ScaleFactor, projectUnits?.Unit); // We need to process the units before we process the rest of the file, since we will scale values as we go along. base.Process(ifcProjectHandle); // process true north - take the first valid representation context that has a true north value. HashSet <IFCAnyHandle> repContexts = IFCAnyHandleUtil.GetAggregateInstanceAttribute <HashSet <IFCAnyHandle> >(ifcProjectHandle, "RepresentationContexts"); bool hasMapConv = false; XYZ geoRef = XYZ.Zero; string geoRefName = null; double trueNorth = 0.0; if (repContexts != null) { foreach (IFCAnyHandle geomRepContextHandle in repContexts) { if (!IFCAnyHandleUtil.IsNullOrHasNoValue(geomRepContextHandle) && IFCAnyHandleUtil.IsSubTypeOf(geomRepContextHandle, IFCEntityType.IfcGeometricRepresentationContext)) { IFCRepresentationContext context = IFCRepresentationContext.ProcessIFCRepresentationContext(geomRepContextHandle); if (TrueNorthDirection == null && context.TrueNorth != null) { // TODO: Verify that we don't have inconsistent true norths. If we do, warn. TrueNorthDirection = new UV(context.TrueNorth.X, context.TrueNorth.Y); } if (WorldCoordinateSystem == null && context.WorldCoordinateSystem != null && !context.WorldCoordinateSystem.IsIdentity) { WorldCoordinateSystem = context.WorldCoordinateSystem; } // Process Map Conversion if any HashSet <IFCAnyHandle> coordOperation = IFCAnyHandleUtil.GetAggregateInstanceAttribute <HashSet <IFCAnyHandle> >(geomRepContextHandle, "HasCoordinateOperation"); if (coordOperation != null) { if (coordOperation.Count > 0) { if (IFCAnyHandleUtil.IsSubTypeOf(coordOperation.FirstOrDefault(), IFCEntityType.IfcMapConversion)) { hasMapConv = true; IFCAnyHandle mapConv = coordOperation.FirstOrDefault(); bool found = false; double eastings = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(mapConv, "Eastings", out found); if (!found) { eastings = 0.0; } double northings = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(mapConv, "Northings", out found); if (!found) { northings = 0.0; } double orthogonalHeight = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(mapConv, "OrthogonalHeight", out found); if (!found) { orthogonalHeight = 0.0; } double xAxisAbs = IFCImportHandleUtil.GetOptionalRealAttribute(mapConv, "XAxisAbscissa", 1.0); double xAxisOrd = IFCImportHandleUtil.GetOptionalRealAttribute(mapConv, "XAxisOrdinate", 0.0); trueNorth = Math.Atan2(xAxisOrd, xAxisAbs); //angleToNorth = -((xAxisAngle > -Math.PI / 2.0) ? xAxisAngle - Math.PI / 2.0 : xAxisAngle + Math.PI * 1.5); double scale = IFCImportHandleUtil.GetOptionalRealAttribute(mapConv, "Scale", 1.0); geoRef = new XYZ(scale * eastings, scale * northings, scale * orthogonalHeight); // Process the IfcProjectedCRS IFCAnyHandle projCRS = IFCAnyHandleUtil.GetInstanceAttribute(mapConv, "TargetCRS"); if (projCRS != null && IFCAnyHandleUtil.IsSubTypeOf(projCRS, IFCEntityType.IfcProjectedCRS)) { geoRefName = IFCImportHandleUtil.GetRequiredStringAttribute(projCRS, "Name", false); string desc = IFCImportHandleUtil.GetOptionalStringAttribute(projCRS, "Description", null); string geodeticDatum = IFCImportHandleUtil.GetOptionalStringAttribute(projCRS, "GeodeticDatum", null); string verticalDatum = IFCImportHandleUtil.GetOptionalStringAttribute(projCRS, "VerticalDatum", null); string mapProj = IFCImportHandleUtil.GetOptionalStringAttribute(projCRS, "MapProjection", null); string mapZone = IFCImportHandleUtil.GetOptionalStringAttribute(projCRS, "MapZone", null); IFCAnyHandle mapUnit = IFCImportHandleUtil.GetOptionalInstanceAttribute(projCRS, "MapUnit"); Document doc = IFCImportFile.TheFile.Document; ProjectInfo projectInfo = doc.ProjectInformation; // We add this here because we want to make sure that external processors (e.g., Navisworks) // get a chance to add a container for the parameters that get added below. In general, // we should probably augment Processor.AddParameter to ensure that CreateOrUpdateElement // is called before anything is attempted to be added. This is a special case, though, // as in Revit we don't actually create an element for the IfcProject. Importer.TheProcessor.CreateOrUpdateElement(Id, GlobalId, EntityType.ToString(), CategoryId.IntegerValue, null); Category category = IFCPropertySet.GetCategoryForParameterIfValid(projectInfo, Id); IFCPropertySet.AddParameterString(doc, projectInfo, category, this, "IfcProjectedCRS.Name", geoRefName, Id); if (!string.IsNullOrEmpty(desc)) { IFCPropertySet.AddParameterString(doc, projectInfo, category, this, "IfcProjectedCRS.Description", desc, Id); } if (!string.IsNullOrEmpty(geodeticDatum)) { IFCPropertySet.AddParameterString(doc, projectInfo, category, this, "IfcProjectedCRS.GeodeticDatum", geodeticDatum, Id); } if (!string.IsNullOrEmpty(verticalDatum)) { IFCPropertySet.AddParameterString(doc, projectInfo, category, this, "IfcProjectedCRS.VerticalDatum", verticalDatum, Id); } if (!string.IsNullOrEmpty(mapProj)) { IFCPropertySet.AddParameterString(doc, projectInfo, category, this, "IfcProjectedCRS.MapProjection", mapProj, Id); } if (!string.IsNullOrEmpty(mapZone)) { IFCPropertySet.AddParameterString(doc, projectInfo, category, this, "IfcProjectedCRS.MapZone", mapZone, Id); } if (!IFCAnyHandleUtil.IsNullOrHasNoValue(mapUnit)) { IFCUnit mapUnitIfc = IFCUnit.ProcessIFCUnit(mapUnit); string unitStr = UnitUtils.GetTypeCatalogStringForUnit(mapUnitIfc.Unit); IFCPropertySet.AddParameterString(doc, projectInfo, category, this, "IfcProjectedCRS.MapUnit", unitStr, Id); double convFactor = UnitUtils.Convert(1.0, mapUnitIfc.Unit, IFCImportFile.TheFile.IFCUnits.GetIFCProjectUnit(SpecTypeId.Length).Unit); eastings = convFactor * eastings; northings = convFactor * northings; orthogonalHeight = convFactor * orthogonalHeight; geoRef = new XYZ(eastings, northings, orthogonalHeight); } } } } } } } ProjectLocation projectLocation = IFCImportFile.TheFile.Document.ActiveProjectLocation; ProjectPosition projectPosition; if (projectLocation != null) { if (hasMapConv) { projectPosition = new ProjectPosition(geoRef.X, geoRef.Y, geoRef.Z, trueNorth); projectLocation.SetProjectPosition(XYZ.Zero, projectPosition); if (!string.IsNullOrEmpty(geoRefName)) { IFCImportFile.TheFile.Document.SiteLocation.SetGeoCoordinateSystem(geoRefName); } } else { // Set initial project location based on the information above. // This may be further modified by the site. trueNorth = 0.0; if (TrueNorthDirection != null) { trueNorth = -Math.Atan2(-TrueNorthDirection.U, TrueNorthDirection.V); } // TODO: Extend this to work properly if the world coordinate system // isn't a simple translation. XYZ origin = XYZ.Zero; if (WorldCoordinateSystem != null) { geoRef = WorldCoordinateSystem.Origin; double angleRot = Math.Atan2(WorldCoordinateSystem.BasisX.Y, WorldCoordinateSystem.BasisX.X); // If it is translation only, or if the WCS rotation is equal to trueNorth, we assume they are the same if (WorldCoordinateSystem.IsTranslation || MathUtil.IsAlmostEqual(angleRot, trueNorth)) { WorldCoordinateSystem = null; } else { // If the trueNorth is not set (=0), set the trueNorth by the rotation of the WCS, otherwise add the angle if (MathUtil.IsAlmostZero(trueNorth)) { trueNorth = angleRot; } else { trueNorth += angleRot; } WorldCoordinateSystem = null; } } projectPosition = new ProjectPosition(geoRef.X, geoRef.Y, geoRef.Z, trueNorth); projectLocation.SetProjectPosition(XYZ.Zero, projectPosition); } } } }
/// <summary> /// Processes IfcRepresentationContext attributes. /// </summary> /// <param name="ifcRepresentationContext">The IfcRepresentationContext handle.</param> override protected void Process(IFCAnyHandle ifcRepresentationContext) { base.Process(ifcRepresentationContext); Identifier = IFCImportHandleUtil.GetOptionalStringAttribute(ifcRepresentationContext, "ContextIdentifier", null); Type = IFCImportHandleUtil.GetOptionalStringAttribute(ifcRepresentationContext, "ContextType", null); if (IFCAnyHandleUtil.IsSubTypeOf(ifcRepresentationContext, IFCEntityType.IfcGeometricRepresentationContext)) { bool found = false; CoordinateSpaceDimension = IFCImportHandleUtil.GetRequiredIntegerAttribute(ifcRepresentationContext, "CoordinateSpaceDimension", out found); if (!found) { CoordinateSpaceDimension = 3; // Don't throw, just set to default 3D. } Precision = IFCImportHandleUtil.GetOptionalScaledLengthAttribute(ifcRepresentationContext, "Precision", IFCImportFile.TheFile.Document.Application.VertexTolerance); IFCAnyHandle worldCoordinateSystem = IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcRepresentationContext, "WorldCoordinateSystem", false); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(worldCoordinateSystem)) { WorldCoordinateSystem = IFCLocation.ProcessIFCAxis2Placement(worldCoordinateSystem); } else { WorldCoordinateSystem = Transform.Identity; } bool isSubContext = IFCImportFile.TheFile.SchemaVersionAtLeast(IFCSchemaVersion.IFC2x2) && IFCAnyHandleUtil.IsSubTypeOf(ifcRepresentationContext, IFCEntityType.IfcGeometricRepresentationSubContext); if (isSubContext) { IFCAnyHandle parentContext = IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcRepresentationContext, "ParentContext", true); ParentContext = IFCRepresentationContext.ProcessIFCRepresentationContext(parentContext); TrueNorth = ParentContext.TrueNorth; } else { // This used to fail for IfcGeometricRepresentationSubContext, because the TrueNorth attribute was derived from // the IfcGeometricRepresentationContext, and the toolkit returned what seemed to be a valid handle that actually // wasn't. The code has now been rewritten to avoid this issue, but we will keep the try/catch block in case we // were also catching other serious issues. try { // By default, True North points in the Y-Direction. IFCAnyHandle trueNorth = IFCImportHandleUtil.GetOptionalInstanceAttribute(ifcRepresentationContext, "TrueNorth"); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(trueNorth)) { TrueNorth = IFCPoint.ProcessNormalizedIFCDirection(trueNorth); } else { TrueNorth = XYZ.BasisY; } } catch { TrueNorth = XYZ.BasisY; } } if (isSubContext) { TargetScale = IFCImportHandleUtil.GetOptionalPositiveRatioAttribute(ifcRepresentationContext, "TargetScale", 1.0); TargetView = IFCEnums.GetSafeEnumerationAttribute <IFCGeometricProjection>(ifcRepresentationContext, "TargetView", IFCGeometricProjection.NotDefined); UserDefinedTargetView = IFCImportHandleUtil.GetOptionalStringAttribute(ifcRepresentationContext, "UserDefinedTargetView", null); } } }