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; } }
override protected void Process(IFCAnyHandle ifcBlock) { base.Process(ifcBlock); bool found = false; XLength = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(ifcBlock, "XLength", out found); if (!found) { Importer.TheLog.LogError(ifcBlock.StepId, "Cannot find the X length of this block.", false); return; } YLength = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(ifcBlock, "YLength", out found); if (!found) { Importer.TheLog.LogError(ifcBlock.StepId, "Cannot find the Y length of this block.", false); return; } ZLength = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(ifcBlock, "ZLength", out found); if (!found) { Importer.TheLog.LogError(ifcBlock.StepId, "Cannot find the Z length of this block.", false); return; } }
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; } }
private void ProcessIFCOffsetCurve3D(IFCAnyHandle ifcCurve) { IFCAnyHandle basisCurve = IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcCurve, "BasisCurve", false); if (basisCurve == null) { return; } bool found = false; double distance = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(ifcCurve, "Distance", out found); if (!found) { distance = 0.0; } try { IFCCurve ifcBasisCurve = IFCCurve.ProcessIFCCurve(basisCurve); 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 { IFCImportFile.TheLog.LogError(ifcCurve.StepId, "Couldn't create offset curve.", false); } }
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 || MathUtil.IsAlmostZero(Depth)) { string depthAsString = IFCUnitUtil.FormatLengthAsString(Depth); Importer.TheLog.LogError(solid.StepId, "extrusion depth of " + depthAsString + " is invalid, aborting.", true); } if (Depth < 0.0) { // Reverse depth and orientation. Depth = -Depth; Direction = -Direction; Importer.TheLog.LogWarning(solid.StepId, "negative extrusion depth is invalid, reversing direction.", false); } }
// TODO: this function should be moved to IFCBoundingBox.cs now that they are fully supported. static private BoundingBoxXYZ ProcessBoundingBox(IFCAnyHandle boundingBoxHnd) { IFCAnyHandle lowerLeftHnd = IFCAnyHandleUtil.GetInstanceAttribute(boundingBoxHnd, "Corner"); XYZ minXYZ = IFCPoint.ProcessScaledLengthIFCCartesianPoint(lowerLeftHnd); bool found = false; double xDim = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(boundingBoxHnd, "XDim", out found); if (!found) { return(null); } double yDim = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(boundingBoxHnd, "YDim", out found); if (!found) { return(null); } double zDim = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(boundingBoxHnd, "ZDim", out found); if (!found) { return(null); } XYZ maxXYZ = new XYZ(minXYZ.X + xDim, minXYZ.Y + yDim, minXYZ.Z + zDim); BoundingBoxXYZ boundingBox = new BoundingBoxXYZ(); boundingBox.set_Bounds(0, minXYZ); boundingBox.set_Bounds(1, maxXYZ); return(boundingBox); }
private void ProcessIFCCircle(IFCAnyHandle ifcCurve, Transform transform) { bool found = false; double radius = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(ifcCurve, "Radius", out found); if (!found) { return; } Curve = Arc.Create(transform.Origin, radius, 0, 2.0 * Math.PI, transform.BasisX, transform.BasisY); }
override protected void Process(IFCAnyHandle ifcCylindricalSurface) { base.Process(ifcCylindricalSurface); bool found = false; Radius = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(ifcCylindricalSurface, "Radius", out found); if (!found) { Importer.TheLog.LogError(ifcCylindricalSurface.StepId, "Cannot find the radius of this cylindrical surface", true); return; } }
/// <summary> /// Converts an IfcVector into a UV or XYZ value. /// </summary> /// <param name="vector">The handle to the IfcVector.</param> /// <returns>An XYZ value corresponding to the value in the file. There are no transformations done in this routine. /// If the return is an XY point, the Z value will be set to 0.</returns> public static XYZ ProcessScaledLengthIFCVector(IFCAnyHandle vector) { if (IFCAnyHandleUtil.IsNullOrHasNoValue(vector)) { Importer.TheLog.LogNullError(IFCEntityType.IfcVector); return(null); } if (!IFCAnyHandleUtil.IsValidSubTypeOf(vector, IFCEntityType.IfcVector)) { Importer.TheLog.LogUnexpectedTypeError(vector, IFCEntityType.IfcVector, false); return(null); } XYZ xyz; int stepId = vector.StepId; if (IFCImportFile.TheFile.XYZMap.TryGetValue(stepId, out xyz)) { return(xyz); } IFCAnyHandle direction = IFCImportHandleUtil.GetRequiredInstanceAttribute(vector, "Orientation", false); if (direction == null) { return(null); } bool found = false; double magnitude = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(vector, "Magnitude", out found); if (!found) { magnitude = 1.0; } XYZ directionXYZ = IFCPoint.ProcessIFCDirection(direction); if (directionXYZ == null) { return(null); } xyz = directionXYZ * magnitude; AddToCaches(stepId, IFCEntityType.IfcVector, xyz); return(xyz); }
override protected void Process(IFCAnyHandle solid) { base.Process(solid); IFCAnyHandle directrix = IFCImportHandleUtil.GetRequiredInstanceAttribute(solid, "Directrix", true); Directrix = IFCCurve.ProcessIFCCurve(directrix); bool found = false; Radius = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(solid, "Radius", out found); if (!found || !Application.IsValidThickness(Radius)) { Importer.TheLog.LogError(solid.StepId, "IfcSweptDiskSolid radius is invalid, aborting.", true); } double innerRadius = IFCImportHandleUtil.GetOptionalScaledLengthAttribute(solid, "InnerRadius", 0.0); if (Application.IsValidThickness(innerRadius)) { if (!Application.IsValidThickness(Radius - innerRadius)) { Importer.TheLog.LogError(solid.StepId, "IfcSweptDiskSolid inner radius is too large, aborting.", true); } InnerRadius = innerRadius; } StartParameter = IFCImportHandleUtil.GetOptionalDoubleAttribute(solid, "StartParam", 0.0); if (StartParameter < MathUtil.Eps()) { StartParameter = 0.0; } double endParameter = IFCImportHandleUtil.GetOptionalDoubleAttribute(solid, "EndParam", -1.0); if (!MathUtil.IsAlmostEqual(endParameter, -1.0)) { if (endParameter < StartParameter + MathUtil.Eps()) { Importer.TheLog.LogWarning(solid.StepId, "IfcSweptDiskSolid swept curve end parameter less than or equal to start parameter, ignoring both.", true); StartParameter = 0.0; } else { EndParameter = endParameter; } } }
override protected void Process(IFCAnyHandle ifcSurface) { base.Process(ifcSurface); IFCAnyHandle extrudedDirection = IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcSurface, "ExtrudedDirection", true); ExtrudedDirection = IFCPoint.ProcessNormalizedIFCDirection(extrudedDirection); bool found = false; Depth = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(ifcSurface, "Depth", out found); if (!found) { Importer.TheLog.LogError(Id, "IfcSurfaceOfLinearExtrusion has no height, ignoring.", true); } }
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) { SetCurve(ifcBasisCurve.Curve.CreateOffset(distance, XYZ.BasisZ)); } else { CurveLoop baseCurveLoop = ifcBasisCurve.GetTheCurveLoop(); if (baseCurveLoop != null) { SetCurveLoop(CurveLoop.CreateViaOffset(baseCurveLoop, distance, XYZ.BasisZ)); } } } catch { Importer.TheLog.LogError(ifcCurve.StepId, "Couldn't create offset curve.", false); } }
protected override void Process(IFCAnyHandle ifcMaterialLayerSetUsage) { base.Process(ifcMaterialLayerSetUsage); IFCAnyHandle ifcMaterialLayerSet = IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcMaterialLayerSetUsage, "ForLayerSet", true); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(ifcMaterialLayerSet)) { MaterialLayerSet = IFCMaterialLayerSet.ProcessIFCMaterialLayerSet(ifcMaterialLayerSet); } string directionAsString = IFCAnyHandleUtil.GetEnumerationAttribute(ifcMaterialLayerSetUsage, "LayerSetDirection"); if (directionAsString == null) { Direction = IFCLayerSetDirection.Axis3; IFCImportFile.TheLog.LogWarning(ifcMaterialLayerSetUsage.StepId, "No LayerSetDirection defined, defaulting to Axis3.", false); } else { Direction = (IFCLayerSetDirection)Enum.Parse(typeof(IFCLayerSetDirection), directionAsString, true); } string directionSenseAsString = IFCAnyHandleUtil.GetEnumerationAttribute(ifcMaterialLayerSetUsage, "DirectionSense"); if (directionSenseAsString == null) { DirectionSense = IFCDirectionSense.Positive; IFCImportFile.TheLog.LogWarning(ifcMaterialLayerSetUsage.StepId, "No DirectionSense defined, defaulting to Positive.", false); } else { DirectionSense = (IFCDirectionSense)Enum.Parse(typeof(IFCDirectionSense), directionSenseAsString, true); } bool found = false; Offset = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(ifcMaterialLayerSetUsage, "OffsetFromReferenceLine", out found); if (!found) { IFCImportFile.TheLog.LogWarning(ifcMaterialLayerSetUsage.StepId, "No Offset defined, defaulting to 0.", false); } }
private void ProcessIFCEllipse(IFCAnyHandle ifcCurve, Transform transform) { bool found = false; double radiusX = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(ifcCurve, "SemiAxis1", out found); if (!found) { return; } double radiusY = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(ifcCurve, "SemiAxis2", out found); if (!found) { return; } Curve = Ellipse.Create(transform.Origin, radiusX, radiusY, transform.BasisX, transform.BasisY, 0, 2.0 * Math.PI); }
protected override void Process(IFCAnyHandle ifcCurve) { base.Process(ifcCurve); bool found = false; double radiusX = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(ifcCurve, "SemiAxis1", out found); if (!found) { Importer.TheLog.LogError(ifcCurve.StepId, "Cannot find the attribute SemiAxis1 of this curve", true); } double radiusY = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(ifcCurve, "SemiAxis2", out found); if (!found) { Importer.TheLog.LogError(ifcCurve.StepId, "Cannot find the attribute SemiAxis2 of this curve", true); } Curve = Ellipse.CreateCurve(Position.Origin, radiusX, radiusY, Position.BasisX, Position.BasisY, 0, 2.0 * Math.PI); }
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; IFCImportFile.TheLog.LogWarning(solid.StepId, "negative extrusion depth is invalid, reversing direction.", false); } } if (!found || !Application.IsValidThickness(Depth)) { string depthAsString = UnitFormatUtils.Format(IFCImportFile.TheFile.Document.GetUnits(), UnitType.UT_Length, Depth, true, false); IFCImportFile.TheLog.LogError(solid.StepId, "extrusion depth of " + depthAsString + " is invalid, aborting.", true); } }
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; } if (!IFCGeometryUtil.IsValidRadius(radius)) { Importer.TheLog.LogError(ifcCurve.StepId, "Invalid radius for this circle: " + radius, false); return; } try { SetCurve(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 = IFCUnitUtil.FormatLengthAsString(radius); Importer.TheLog.LogError(Id, "Found a circle with radius of " + lengthAsString + ", ignoring.", false); } else { Importer.TheLog.LogError(Id, ex.Message, false); } SetCurve(null); } }
protected override void Process(IFCAnyHandle ifcMaterialLayerSetUsage) { base.Process(ifcMaterialLayerSetUsage); IFCAnyHandle ifcMaterialLayerSet = IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcMaterialLayerSetUsage, "ForLayerSet", true); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(ifcMaterialLayerSet)) { MaterialLayerSet = IFCMaterialLayerSet.ProcessIFCMaterialLayerSet(ifcMaterialLayerSet); } Direction = IFCEnums.GetSafeEnumerationAttribute(ifcMaterialLayerSetUsage, "LayerSetDirection", IFCLayerSetDirection.Axis3); DirectionSense = IFCEnums.GetSafeEnumerationAttribute(ifcMaterialLayerSetUsage, "DirectionSense", IFCDirectionSense.Positive); bool found = false; Offset = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(ifcMaterialLayerSetUsage, "OffsetFromReferenceLine", out found); if (!found) { Importer.TheLog.LogWarning(ifcMaterialLayerSetUsage.StepId, "No Offset defined, defaulting to 0.", false); } }
/// <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); } } } }