// TODO: handle SiteAddress. /// <summary> /// Check if an object placement is relative to the site's placement, and fix it if necessary. /// </summary> /// <param name="productEntity">The entity being checked.</param> /// <param name="productStepId">The id of the entity being checked.</param> /// <param name="objectPlacement">The object placement handle.</param> public static void CheckObjectPlacementIsRelativeToSite(IFCProduct productEntity, int productStepId, IFCAnyHandle objectPlacement) { if (BaseSiteOffset == null) { return; } IFCLocation productEntityLocation = productEntity.ObjectLocation; if (productEntityLocation != null && productEntityLocation.RelativeToSite == false) { if (!(productEntity is IFCSite)) { if (!IFCAnyHandleUtil.IsSubTypeOf(objectPlacement, IFCEntityType.IfcGridPlacement)) { Importer.TheLog.LogWarning(productStepId, "The local placement (#" + objectPlacement.StepId + ") of this entity was not relative to the IfcSite's local placement, patching.", false); } if (productEntityLocation.RelativeTransform == null) { productEntityLocation.RelativeTransform = Transform.CreateTranslation(-BaseSiteOffset); } else { productEntityLocation.RelativeTransform.Origin -= BaseSiteOffset; } } productEntityLocation.RelativeToSite = true; } }
/// <summary> /// Create a dummy IFCLocation that contains only a relative transform. /// </summary> /// <param name="relativeTransform">The transform associated with the location.</param> /// <returns>The new IFCLocation.</returns> /// <remarks> /// This is intended for use for IFCSites, whose location has either been modified /// by the RefElevation parameter, or by being moved far from the origin. /// </remarks> static public IFCLocation CreateDummyLocation(Transform relativeTransform) { IFCLocation dummyLocation = new IFCLocation(); dummyLocation.RelativeTransform = relativeTransform; return(dummyLocation); }
public static void CheckObjectPlacementIsRelativeToSite(IFCProduct productEntity, int productStepId, int objectPlacementStepId) { IFCLocation productEntityLocation = productEntity.ObjectLocation; if (ActiveSite != null && productEntityLocation != null && productEntityLocation.RelativeToSite == false) { if (!(productEntity is IFCSite)) { IFCLocation activeSiteLocation = ActiveSite.ObjectLocation; if (activeSiteLocation != null) { Importer.TheLog.LogWarning(productStepId, "The local placement (#" + objectPlacementStepId + ") of this entity was not relative to the IfcSite's local placement, patching.", false); Transform siteTransform = activeSiteLocation.TotalTransform; if (siteTransform != null) { Transform siteTransformInverse = siteTransform.Inverse; Transform originalTotalTransform = productEntityLocation.TotalTransform; if (originalTotalTransform == null) { productEntityLocation.RelativeTransform = siteTransformInverse; } else { productEntityLocation.RelativeTransform = originalTotalTransform.Multiply(siteTransformInverse); } } productEntityLocation.RelativeTo = activeSiteLocation; } } productEntityLocation.RelativeToSite = true; } }
override protected void Process(IFCAnyHandle solid) { base.Process(solid); // We will not fail if the axis is not given, but instead assume it to be the identity in the LCS. IFCAnyHandle axis = IFCImportHandleUtil.GetRequiredInstanceAttribute(solid, "Axis", false); if (axis != null) { Axis = IFCLocation.ProcessIFCAxis1Placement(axis); } else { Axis = Transform.Identity; } bool found = false; Angle = IFCImportHandleUtil.GetRequiredScaledAngleAttribute(solid, "Angle", out found); // TODO: IFCImportFile.TheFile.Document.Application.IsValidAngle(Angle) if (!found || Angle < MathUtil.Eps()) { Importer.TheLog.LogError(solid.StepId, "revolve angle is invalid, aborting.", true); } }
/// <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); } } }
override protected void Process(IFCAnyHandle ifcSurface) { base.Process(ifcSurface); IFCAnyHandle position = IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcSurface, "Position", true); Position = IFCLocation.ProcessIFCAxis2Placement(position); }
/// <summary> /// Creates or populates Revit elements based on the information contained in this class. /// </summary> /// <param name="doc">The document.</param> protected override void Create(Document doc) { // Only set the project location for the site that contains the building. bool hasBuilding = false; foreach (IFCObjectDefinition objectDefinition in ComposedObjectDefinitions) { if (objectDefinition is IFCBuilding) { hasBuilding = true; break; } } if (hasBuilding) { ProjectLocation projectLocation = doc.ActiveProjectLocation; if (projectLocation != null) { SiteLocation siteLocation = projectLocation.SiteLocation; if (siteLocation != null) { if (RefLatitude.HasValue) { siteLocation.Latitude = RefLatitude.Value * Math.PI / 180.0; } if (RefLongitude.HasValue) { siteLocation.Longitude = RefLongitude.Value * Math.PI / 180.0; } } if (ObjectLocation != null) { XYZ projectLoc = (ObjectLocation.RelativeTransform != null) ? ObjectLocation.RelativeTransform.Origin : XYZ.Zero; // Get true north from IFCProject. double trueNorth = 0.0; IList <double> trueNorthList = IFCImportFile.TheFile.IFCProject.TrueNorthDirection; if (trueNorthList != null && trueNorthList.Count >= 2) { trueNorth = Math.Atan2(trueNorthList[1], trueNorthList[0]); } ProjectPosition projectPosition = new ProjectPosition(projectLoc.X, projectLoc.Y, RefElevation, trueNorth); XYZ origin = new XYZ(0, 0, 0); projectLocation.set_ProjectPosition(origin, projectPosition); // Now that we've set the project position, remove the site relative transform. IFCLocation.RemoveRelativeTransformForSite(this); } } } base.Create(doc); }
/// <summary> /// Processes object placement of the product. /// </summary> /// <param name="ifcProduct">The IfcProduct handle.</param> protected void ProcessObjectPlacement(IFCAnyHandle ifcProduct) { IFCAnyHandle objectPlacement = IFCAnyHandleUtil.GetInstanceAttribute(ifcProduct, "ObjectPlacement"); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(objectPlacement)) { ObjectLocation = IFCLocation.ProcessIFCObjectPlacement(objectPlacement); } }
/// <summary> /// Processes object placement of the product. /// </summary> /// <param name="ifcProduct">The IfcProduct handle.</param> protected void ProcessObjectPlacement(IFCAnyHandle ifcProduct) { IFCAnyHandle objectPlacement = IFCAnyHandleUtil.GetInstanceAttribute(ifcProduct, "ObjectPlacement"); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(objectPlacement)) { ObjectLocation = IFCLocation.ProcessIFCObjectPlacement(objectPlacement); IFCSite.ActiveSiteSetter.CheckObjectPlacementIsRelativeToSite(this, ifcProduct.StepId, objectPlacement.StepId); } }
override protected void Process(IFCAnyHandle objectPlacement) { base.Process(objectPlacement); IFCAnyHandle placementRelTo = IFCAnyHandleUtil.GetInstanceAttribute(objectPlacement, "PlacementRelTo"); IFCAnyHandle relativePlacement = IFCAnyHandleUtil.GetInstanceAttribute(objectPlacement, "RelativePlacement"); m_RelativeTo = IFCAnyHandleUtil.IsNullOrHasNoValue(placementRelTo) ? null : ProcessIFCObjectPlacement(placementRelTo); RelativeTransform = ProcessIFCAxis2Placement(relativePlacement); }
/// <summary> /// Cleans out the IFCEntity to save memory. /// </summary> public override void CleanEntity() { base.CleanEntity(); ObjectLocation = null; m_ProductRepresentation = null; m_Solids = null; m_Voids = null; }
/// <summary> /// Creates or populates Revit elements based on the information contained in this class. /// </summary> /// <param name="doc">The document.</param> protected override void Create(Document doc) { base.Create(doc); IFCLocation.WarnIfFaraway(this); // IfcBuilding usually won't create an element, as it contains no geometry. // If it doesn't, use the ProjectInfo element in the document to store its parameters. if (CreatedElementId == ElementId.InvalidElementId) { CreatedElementId = Importer.TheCache.ProjectInformationId; } }
protected override void Process(IFCAnyHandle ifcCurve) { base.Process(ifcCurve); IFCAnyHandle position = IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcCurve, "Position", false); if (position == null) { return; } Position = IFCLocation.ProcessIFCAxis2Placement(position); }
override protected void Process(IFCAnyHandle ifcSurface) { base.Process(ifcSurface); IFCAnyHandle ifcAxisPosition = IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcSurface, "AxisPosition", true); AxisPosition = IFCLocation.ProcessIFCAxis1Placement(ifcAxisPosition); if (AxisPosition == null) { Importer.TheLog.LogError(ifcSurface.StepId, "Cannot find the axis position of this surface of revolution", true); } }
override protected void Process(IFCAnyHandle objectPlacement) { base.Process(objectPlacement); IFCAnyHandle placementRelTo = IFCAnyHandleUtil.GetInstanceAttribute(objectPlacement, "PlacementRelTo"); IFCAnyHandle relativePlacement = IFCAnyHandleUtil.GetInstanceAttribute(objectPlacement, "RelativePlacement"); m_RelativeTo = IFCAnyHandleUtil.IsNullOrHasNoValue(placementRelTo) ? null : ProcessIFCObjectPlacement(placementRelTo); RelativeTransform = ProcessIFCAxis2Placement(relativePlacement); // If the location that this is relative to is relative to the site location, then so is this. // This relies on RelativeToSite for the IfcSite local placement to be set to true before any other entities are processed. if (m_RelativeTo != null) { RelativeToSite = m_RelativeTo.RelativeToSite; } }
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); } }
override protected void Process(IFCAnyHandle solid) { base.Process(solid); IFCAnyHandle sweptArea = IFCImportHandleUtil.GetRequiredInstanceAttribute(solid, "SweptArea", true); SweptArea = IFCProfileDef.ProcessIFCProfileDef(sweptArea); IFCAnyHandle location = IFCImportHandleUtil.GetRequiredInstanceAttribute(solid, "Position", false); if (location != null) { Position = IFCLocation.ProcessIFCAxis2Placement(location); } else { Position = Transform.Identity; } }
override protected void Process(IFCAnyHandle solid) { base.Process(solid); bool found = false; bool agreementFlag = IFCImportHandleUtil.GetRequiredBooleanAttribute(solid, "AgreementFlag", out found); if (found) { AgreementFlag = agreementFlag; } IFCAnyHandle baseSurface = IFCImportHandleUtil.GetRequiredInstanceAttribute(solid, "BaseSurface", true); BaseSurface = IFCSurface.ProcessIFCSurface(baseSurface); if (!(BaseSurface is IFCPlane)) { Importer.TheLog.LogUnhandledSubTypeError(baseSurface, IFCEntityType.IfcSurface, true); } if (IFCAnyHandleUtil.IsValidSubTypeOf(solid, IFCEntityType.IfcPolygonalBoundedHalfSpace)) { IFCAnyHandle position = IFCImportHandleUtil.GetRequiredInstanceAttribute(solid, "Position", false); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(position)) { BaseBoundingCurveTransform = IFCLocation.ProcessIFCAxis2Placement(position); } else { BaseBoundingCurveTransform = Transform.Identity; } IFCAnyHandle boundaryCurveHandle = IFCImportHandleUtil.GetRequiredInstanceAttribute(solid, "PolygonalBoundary", true); BaseBoundingCurve = IFCCurve.ProcessIFCCurve(boundaryCurveHandle); if (BaseBoundingCurve == null || BaseBoundingCurve.GetTheCurveLoop() == null) { Importer.TheLog.LogError(Id, "IfcPolygonalBoundedHalfSpace has an invalid boundary, ignoring.", true); } } }
/// <summary> /// Processes IfcRepresentationMap attributes. /// </summary> /// <param name="ifcRepresentationMap">The IfcRepresentationMap handle.</param> protected override void Process(IFCAnyHandle ifcRepresentationMap) { base.Process(ifcRepresentationMap); IFCAnyHandle mappingOrigin = IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcRepresentationMap, "MappingOrigin", false); if (mappingOrigin != null) { MappingOrigin = IFCLocation.ProcessIFCAxis2Placement(mappingOrigin); } else { MappingOrigin = Transform.Identity; } IFCAnyHandle mappedRepresentation = IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcRepresentationMap, "MappedRepresentation", false); if (mappedRepresentation != null) { MappedRepresentation = IFCRepresentation.ProcessIFCRepresentation(mappedRepresentation); } }
private void ProcessIFCConic(IFCAnyHandle ifcCurve) { IFCAnyHandle position = IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcCurve, "Position", false); if (position == null) { return; } Transform transform = IFCLocation.ProcessIFCAxis2Placement(position); if (IFCAnyHandleUtil.IsSubTypeOf(ifcCurve, IFCEntityType.IfcCircle)) { ProcessIFCCircle(ifcCurve, transform); } else if (IFCAnyHandleUtil.IsSubTypeOf(ifcCurve, IFCEntityType.IfcEllipse)) { ProcessIFCEllipse(ifcCurve, transform); } else { IFCImportFile.TheLog.LogUnhandledSubTypeError(ifcCurve, IFCEntityType.IfcConic, true); } }
public static void ProcessSiteLocations(Document doc, IList <IFCSite> sites) { BaseSiteOffset = null; // Ideally, in most cases, this routine will do nothing. In particular, that is // true if the project has an arbitrary number of sites that are "close" to the // origin. if (sites == null || sites.Count == 0) { return; } ProjectLocation projectLocation = doc.ActiveProjectLocation; if (projectLocation == null) { return; } // If there is one site, and it is far from the origin, then we will move the site // close to the origin, give a warning, and set the shared coordinates in the file. // If there is more than one site, and at least one site is far from the origin: // 1. If all of the sites have an origin close to one another, then we will move the // site close to the origin based on the first site encountered, give a warning, // and set the shared coordinates in the file and the rest of the sites relative to // the first site. // 2. If the sites do not have origins close to one another, then we will do nothing // and give an error that the site is far from the origin and may have poor // performance and appearance. int numSites = sites.Count; bool hasSiteLocation = false; // First pass: deal with latitude and longitude. for (int ii = 0; ii < numSites; ii++) { IFCSite currSite = sites[ii]; // Set the project latitude and longitude if the information is available, and // it hasn't already been set. SiteLocation siteLocation = projectLocation.GetSiteLocation(); if (siteLocation != null) { // Some Tekla files may have invalid information here that would otherwise cause the // link to fail. Recover with a warning. try { bool foundSiteLocation = (currSite.RefLatitude.HasValue && currSite.RefLongitude.HasValue); if (foundSiteLocation) { if (hasSiteLocation) { Importer.TheLog.LogWarning(currSite.Id, "Duplicate latitude or longitude value supplied for IFCSITE, ignoring.", false); } else { hasSiteLocation = true; siteLocation.Latitude = currSite.RefLatitude.Value * Math.PI / 180.0; siteLocation.Longitude = currSite.RefLongitude.Value * Math.PI / 180.0; } } } catch (Exception ex) { Importer.TheLog.LogWarning(currSite.Id, "Invalid latitude or longitude value supplied for IFCSITE: " + ex.Message, false); } } } int?distantOriginFirstSiteId = null; for (int ii = 0; ii < numSites; ii++) { IFCSite currSite = sites[ii]; // This is effectively no offset. This is good, as long as we don't have // a distance origin. In that case, we will warn and not do any special offsets. if (currSite.ObjectLocation?.RelativeTransform == null) { if (distantOriginFirstSiteId.HasValue) { BaseSiteOffset = null; break; } continue; } XYZ projectLoc = currSite.ObjectLocation.RelativeTransform.Origin; XYZ offset = new XYZ(projectLoc.X, projectLoc.Y, projectLoc.Z); if (XYZ.IsWithinLengthLimits(offset)) { if (distantOriginFirstSiteId.HasValue) { BaseSiteOffset = null; break; } continue; } if (BaseSiteOffset == null) { distantOriginFirstSiteId = currSite.Id; // If the index is greater than 0, then we have found some sites close to the // origin. That means we have incompatible origins which is an issue. if (ii == 0) { BaseSiteOffset = offset; } else { break; } } } if (BaseSiteOffset != null) { // Modify the RelativeTransforms for each of these sites. // Note that the RelativeTransform must be defined to have gotten here. for (int ii = 0; ii < numSites; ii++) { XYZ currentOffset = new XYZ(-BaseSiteOffset.X, -BaseSiteOffset.Y, -BaseSiteOffset.Z /*+ sites[ii].RefElevation*/); Transform newSiteTransform = sites[ii].ObjectLocation.TotalTransform; newSiteTransform.Origin += currentOffset; sites[ii].ObjectLocation = IFCLocation.CreateDummyLocation(newSiteTransform); } // Register the offset by moving the Shared Coordinates away ProjectPosition pPos = projectLocation.GetProjectPosition(XYZ.Zero); pPos.EastWest += BaseSiteOffset.X; pPos.NorthSouth += BaseSiteOffset.Y; pPos.Elevation += BaseSiteOffset.Z; projectLocation.SetProjectPosition(XYZ.Zero, pPos); } else { // In this case, we just have to make sure that the RefElevation is included in // the site transform. for (int ii = 0; ii < numSites; ii++) { if (MathUtil.IsAlmostZero(sites[ii].RefElevation)) { continue; } if (sites[ii].ObjectLocation == null || sites[ii].ObjectLocation.RelativeTransform == null) { XYZ currentOffset = XYZ.Zero; sites[ii].ObjectLocation = IFCLocation.CreateDummyLocation(Transform.CreateTranslation(currentOffset)); } else { double currRefElevation = sites[ii].RefElevation; double currZOffset = sites[ii].ObjectLocation.RelativeTransform.Origin.Z; if (!MathUtil.IsAlmostEqual(currZOffset, currRefElevation)) { Transform newSiteTransform = sites[ii].ObjectLocation.TotalTransform; sites[ii].ObjectLocation = IFCLocation.CreateDummyLocation(newSiteTransform); } } } } if (BaseSiteOffset == null && distantOriginFirstSiteId.HasValue) { Importer.TheLog.LogError(distantOriginFirstSiteId.Value, "There are multiple sites in the file that are located far away from each other. This may result in poor visualization of the data.", false); } }
/// <summary> /// Creates or populates Revit elements based on the information contained in this class. /// </summary> /// <param name="doc">The document.</param> protected override void Create(Document doc) { IFCLocation.WarnIfFaraway(this); // We may re-use the ActiveView Level and View, since we can't delete them. // We will consider that we "created" this level and view for creation metrics. Level level = Importer.TheCache.UseElementByGUID <Level>(doc, GlobalId); bool reusedLevel = false; bool foundLevel = false; if (level == null) { if (ExistingLevelIdToReuse != ElementId.InvalidElementId) { level = doc.GetElement(ExistingLevelIdToReuse) as Level; Importer.TheCache.UseElement(level); ExistingLevelIdToReuse = ElementId.InvalidElementId; reusedLevel = true; } } else { foundLevel = true; } double referenceElevation = GetReferenceElevation(); double totalElevation = Elevation + referenceElevation; if (level == null) { level = Level.Create(doc, totalElevation); } else { level.Elevation = totalElevation; } if (level != null) { CreatedElementId = level.Id; } if (CreatedElementId != ElementId.InvalidElementId) { if (!foundLevel) { if (!reusedLevel) { ElementId viewPlanTypeId = IFCBuildingStorey.GetViewPlanTypeId(doc); if (viewPlanTypeId != ElementId.InvalidElementId) { ViewPlan viewPlan = ViewPlan.Create(doc, viewPlanTypeId, CreatedElementId); if (viewPlan != null) { CreatedViewId = viewPlan.Id; } } if (CreatedViewId == ElementId.InvalidElementId) { Importer.TheLog.LogAssociatedCreationError(this, typeof(ViewPlan)); } } else { if (doc.ActiveView != null) { CreatedViewId = doc.ActiveView.Id; } } } } else { Importer.TheLog.LogCreationError(this, null, false); } TraverseSubElements(doc); }
/// <summary> /// Creates or populates Revit elements based on the information contained in this class. /// </summary> /// <param name="doc">The document.</param> protected override void Create(Document doc) { // Only set the project location for the site that contains the building. bool hasBuilding = false; foreach (IFCObjectDefinition objectDefinition in ComposedObjectDefinitions) { if (objectDefinition is IFCBuilding) { hasBuilding = true; break; } } if (hasBuilding) { ProjectLocation projectLocation = doc.ActiveProjectLocation; if (projectLocation != null) { SiteLocation siteLocation = projectLocation.GetSiteLocation(); if (siteLocation != null) { // Some Tekla files may have invalid information here that would otherwise cause the // link to fail. Recover with a warning. try { if (RefLatitude.HasValue) { siteLocation.Latitude = RefLatitude.Value * Math.PI / 180.0; } if (RefLongitude.HasValue) { siteLocation.Longitude = RefLongitude.Value * Math.PI / 180.0; } } catch (Exception ex) { Importer.TheLog.LogWarning(Id, "Invalid latitude or longitude value supplied for IFCSITE: " + ex.Message, false); } } if (ObjectLocation != null) { XYZ projectLoc = (ObjectLocation.RelativeTransform != null) ? ObjectLocation.RelativeTransform.Origin : XYZ.Zero; if (!MathUtil.IsAlmostZero(projectLoc.Z)) { Importer.TheLog.LogError(Id, "The Z-value of the IfcSite object placement relative transform should be 0. This will be ignored in favor of the RefElevation value.", false); } // Get true north from IFCProject. double trueNorth = 0.0; UV trueNorthUV = IFCImportFile.TheFile.IFCProject.TrueNorthDirection; if (trueNorthUV != null) { double geometricAngle = Math.Atan2(trueNorthUV.V, trueNorthUV.U); // Convert from geometric angle to compass direction. // This involves two steps: (1) subtract PI/2 from the angle, staying in (-PI, PI], then (2) reversing the result. trueNorth = (geometricAngle > -Math.PI / 2.0) ? geometricAngle - Math.PI / 2.0 : geometricAngle + Math.PI * 1.5; trueNorth = -trueNorth; } ProjectPosition projectPosition = new ProjectPosition(projectLoc.X, projectLoc.Y, RefElevation, trueNorth); projectLocation.SetProjectPosition(XYZ.Zero, projectPosition); // Now that we've set the project position, remove the site relative transform, if the file is created correctly (that is, all entities contained in the site // have the local placements relative to the site. IFCLocation.RemoveRelativeTransformForSite(this); } } } base.Create(doc); if (hasBuilding) { // There should only be one IfcSite in the file, but in case there are multiple, we want to make sure that the one // containing the IfcBuilding has its parameters stored somewhere. // In the case where we didn't create an element above, use the ProjectInfo element in the document to store its parameters. if (CreatedElementId == ElementId.InvalidElementId) { CreatedElementId = Importer.TheCache.ProjectInformationId; } } }
/// <summary> /// Creates or populates Revit elements based on the information contained in this class. /// </summary> /// <param name="doc">The document.</param> protected override void Create(Document doc) { // Only set the project location for the site that contains the building. bool hasBuilding = false; foreach (IFCObjectDefinition objectDefinition in ComposedObjectDefinitions) { if (objectDefinition is IFCBuilding) { hasBuilding = true; break; } } if (hasBuilding) { ProjectLocation projectLocation = doc.ActiveProjectLocation; if (projectLocation != null) { SiteLocation siteLocation = projectLocation.SiteLocation; if (siteLocation != null) { if (RefLatitude.HasValue) { siteLocation.Latitude = RefLatitude.Value * Math.PI / 180.0; } if (RefLongitude.HasValue) { siteLocation.Longitude = RefLongitude.Value * Math.PI / 180.0; } } if (ObjectLocation != null) { XYZ projectLoc = (ObjectLocation.RelativeTransform != null) ? ObjectLocation.RelativeTransform.Origin : XYZ.Zero; // Get true north from IFCProject. double trueNorth = 0.0; IList <double> trueNorthList = IFCImportFile.TheFile.IFCProject.TrueNorthDirection; if (trueNorthList != null && trueNorthList.Count >= 2) { double geometricAngle = Math.Atan2(trueNorthList[1], trueNorthList[0]); // Convert from geometric angle to compass direction. // This involves two steps: (1) subtract PI/2 from the angle, staying in (-PI, PI], then (2) reversing the result. trueNorth = (geometricAngle > -Math.PI / 2.0) ? geometricAngle - Math.PI / 2.0 : geometricAngle + Math.PI * 1.5; trueNorth = -trueNorth; } ProjectPosition projectPosition = new ProjectPosition(projectLoc.X, projectLoc.Y, RefElevation, trueNorth); XYZ origin = new XYZ(0, 0, 0); projectLocation.set_ProjectPosition(origin, projectPosition); // Now that we've set the project position, remove the site relative transform. IFCLocation.RemoveRelativeTransformForSite(this); } } } base.Create(doc); if (hasBuilding) { // There should only be one IfcSite in the file, but in case there are multiple, we want to make sure that the one // containing the IfcBuilding has its parameters stored somewhere. // In the case where we didn't create an element above, use the ProjectInfo element in the document to store its parameters. if (CreatedElementId == ElementId.InvalidElementId) { CreatedElementId = Importer.TheCache.ProjectInformationId; } } }
/// <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); } } }
/// <summary> /// Processes object placement of the product. /// </summary> /// <param name="ifcProduct">The IfcProduct handle.</param> protected void ProcessObjectPlacement(IFCAnyHandle ifcProduct) { IFCAnyHandle objectPlacement = IFCAnyHandleUtil.GetInstanceAttribute(ifcProduct, "ObjectPlacement"); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(objectPlacement)) ObjectLocation = IFCLocation.ProcessIFCObjectPlacement(objectPlacement); }