/// <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 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); } }
static Transform ProcessAxis2Placement2D(IFCAnyHandle placement) { IFCAnyHandle refDirection = IFCAnyHandleUtil.GetInstanceAttribute(placement, "RefDirection"); XYZ refDirectionX = IFCAnyHandleUtil.IsNullOrHasNoValue(refDirection) ? XYZ.BasisX : IFCPoint.ProcessNormalizedIFCDirection(refDirection); XYZ refDirectionY = new XYZ(-refDirectionX.Y, refDirectionX.X, 0.0); Transform lcs = ProcessPlacementBase(placement); lcs.BasisX = refDirectionX; lcs.BasisY = refDirectionY; lcs.BasisZ = refDirectionX.CrossProduct(refDirectionY); return(lcs); }
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); } }
static Transform ProcessAxis2Placement3D(IFCAnyHandle placement) { IFCAnyHandle axis = IFCAnyHandleUtil.GetInstanceAttribute(placement, "Axis"); IFCAnyHandle refDirection = IFCAnyHandleUtil.GetInstanceAttribute(placement, "RefDirection"); XYZ axisXYZ = IFCAnyHandleUtil.IsNullOrHasNoValue(axis) ? XYZ.BasisZ : IFCPoint.ProcessNormalizedIFCDirection(axis); XYZ refDirectionXYZ = IFCAnyHandleUtil.IsNullOrHasNoValue(refDirection) ? XYZ.BasisX : IFCPoint.ProcessNormalizedIFCDirection(refDirection); Transform lcs = ProcessPlacementBase(placement); XYZ lcsX = (refDirectionXYZ - refDirectionXYZ.DotProduct(axisXYZ) * axisXYZ).Normalize(); XYZ lcsY = axisXYZ.CrossProduct(lcsX).Normalize(); lcs.BasisX = lcsX; lcs.BasisY = lcsY; lcs.BasisZ = axisXYZ; return(lcs); }
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); } }
static Transform ProcessAxis2Placement3D(IFCAnyHandle placement) { IFCAnyHandle axis = IFCAnyHandleUtil.GetInstanceAttribute(placement, "Axis"); IFCAnyHandle refDirection = IFCAnyHandleUtil.GetInstanceAttribute(placement, "RefDirection"); XYZ axisXYZ = IFCAnyHandleUtil.IsNullOrHasNoValue(axis) ? XYZ.BasisZ : IFCPoint.ProcessNormalizedIFCDirection(axis, false); XYZ refDirectionXYZ = IFCAnyHandleUtil.IsNullOrHasNoValue(refDirection) ? XYZ.BasisX : IFCPoint.ProcessNormalizedIFCDirection(refDirection, false); if (axisXYZ.IsZeroLength()) { Importer.TheLog.LogError(axis.StepId, "Local transform contains 0 length axis vector, reverting to Z-axis.", false); axisXYZ = XYZ.BasisZ; } if (refDirectionXYZ.IsZeroLength()) { Importer.TheLog.LogError(refDirection.StepId, "Local transform contains 0 length reference vector, reverting to X-axis.", false); refDirectionXYZ = XYZ.BasisX; } Transform lcs = ProcessPlacementBase(placement); XYZ lcsX = (refDirectionXYZ - refDirectionXYZ.DotProduct(axisXYZ) * axisXYZ).Normalize(); XYZ lcsY = axisXYZ.CrossProduct(lcsX).Normalize(); if (lcsX.IsZeroLength() || lcsY.IsZeroLength()) { Importer.TheLog.LogError(placement.StepId, "Local transform contains 0 length vectors.", true); } lcs.BasisX = lcsX; lcs.BasisY = lcsY; lcs.BasisZ = axisXYZ; return(lcs); }
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 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> /// Convert an IfcAxis1Placement into a transform. /// </summary> /// <param name="placement">The placement handle.</param> /// <returns>The transform.</returns> public static Transform ProcessIFCAxis1Placement(IFCAnyHandle ifcPlacement) { if (IFCAnyHandleUtil.IsNullOrHasNoValue(ifcPlacement)) { return(Transform.Identity); } Transform transform; if (IFCImportFile.TheFile.TransformMap.TryGetValue(ifcPlacement.StepId, out transform)) { return(transform); } if (!IFCAnyHandleUtil.IsValidSubTypeOf(ifcPlacement, IFCEntityType.IfcAxis1Placement)) { Importer.TheLog.LogUnhandledSubTypeError(ifcPlacement, "IfcAxis1Placement", false); transform = Transform.Identity; } IFCAnyHandle ifcAxis = IFCAnyHandleUtil.GetInstanceAttribute(ifcPlacement, "Axis"); XYZ norm = IFCAnyHandleUtil.IsNullOrHasNoValue(ifcAxis) ? XYZ.BasisZ : IFCPoint.ProcessNormalizedIFCDirection(ifcAxis); transform = ProcessPlacementBase(ifcPlacement); Plane arbitraryPlane = Plane.CreateByNormalAndOrigin(norm, transform.Origin); transform.BasisX = arbitraryPlane.XVec; transform.BasisY = arbitraryPlane.YVec; transform.BasisZ = norm; IFCImportFile.TheFile.TransformMap[ifcPlacement.StepId] = transform; return(transform); }
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); }