/// <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); } }
protected override void Process(IFCAnyHandle ifcCurve) { base.Process(ifcCurve); IList <IFCAnyHandle> points = IFCAnyHandleUtil.GetAggregateInstanceAttribute <List <IFCAnyHandle> >(ifcCurve, "Points"); int numPoints = points.Count; if (numPoints < 2) { string msg = "IfcPolyLine had " + numPoints + ", expected at least 2, ignoring"; Importer.TheLog.LogError(Id, msg, false); return; } IList <XYZ> pointXYZs = new List <XYZ>(); foreach (IFCAnyHandle point in points) { XYZ pointXYZ = IFCPoint.ProcessScaledLengthIFCCartesianPoint(point); pointXYZs.Add(pointXYZ); } if (pointXYZs.Count != numPoints) { Importer.TheLog.LogError(Id, "Some of the IFC points cannot be converted to Revit points", true); } CurveLoop = IFCGeometryUtil.CreatePolyCurveLoop(pointXYZs, points, Id, false); Curve = IFCGeometryUtil.CreateCurveFromPolyCurveLoop(CurveLoop, pointXYZs); }
override protected void Process(IFCAnyHandle ifcPolyLoop) { base.Process(ifcPolyLoop); List <IFCAnyHandle> ifcPolygon = IFCAnyHandleUtil.GetAggregateInstanceAttribute <List <IFCAnyHandle> >(ifcPolyLoop, "Polygon"); if (ifcPolygon == null) { return; // TODO: WARN } Polygon = IFCPoint.ProcessScaledLengthIFCCartesianPoints(ifcPolygon); // Check for duplicate points, including wrapping around, and remove them. int numVertices = Polygon.Count; for (int ii = numVertices - 1; (ii != -1) && numVertices >= 3; ii--) { if (MathUtil.IsAlmostEqualAbsolute(Polygon[ii], Polygon[(ii + 1) % numVertices])) { Importer.TheLog.LogError(ifcPolyLoop.StepId, "The polygon vertex at index " + ii + " is a duplicate, removing.", false); Polygon.RemoveAt(ii); numVertices--; } } if (numVertices < 3) { // This used to throw an error. However, we found files that threw this error // thousands of times, causing incredibly slow links. Instead, null out the // data and log an error. Polygon = null; Importer.TheLog.LogError(ifcPolyLoop.StepId, "Polygon attribute has only " + numVertices + " vertices, 3 expected.", false); } }
override protected void Process(IFCAnyHandle ifcPolyLoop) { base.Process(ifcPolyLoop); List <IFCAnyHandle> ifcPolygon = IFCAnyHandleUtil.GetAggregateInstanceAttribute <List <IFCAnyHandle> >(ifcPolyLoop, "Polygon"); if (ifcPolygon == null) { return; // TODO: WARN } Polygon = IFCPoint.ProcessScaledLengthIFCCartesianPoints(ifcPolygon); int numVertices = Polygon.Count; if (numVertices > 1) { if (MathUtil.IsAlmostEqualAbsolute(Polygon[0], Polygon[numVertices - 1])) { // LOG: Warning: #: First and last points are almost identical, removing extra point. Polygon.RemoveAt(numVertices - 1); numVertices--; } } if (numVertices < 3) { // This used to throw an error. However, we found files that threw this error // thousands of times, causing incredibly slow links. Instead, null out the // data and log an error. Polygon = null; Importer.TheLog.LogError(ifcPolyLoop.StepId, "Polygon attribute has only " + numVertices + " vertices, 3 expected.", false); } }
protected override void Process(IFCAnyHandle ifcCurve) { base.Process(ifcCurve); IFCAnyHandle pnt = IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcCurve, "Pnt", false); if (pnt == null) { return; } IFCAnyHandle dir = IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcCurve, "Dir", false); if (dir == null) { return; } XYZ pntXYZ = IFCPoint.ProcessScaledLengthIFCCartesianPoint(pnt); XYZ dirXYZ = IFCUnitUtil.ScaleLength(IFCPoint.ProcessIFCVector(dir)); ParametericScaling = dirXYZ.GetLength(); if (MathUtil.IsAlmostZero(ParametericScaling)) { Importer.TheLog.LogWarning(ifcCurve.StepId, "Line has zero length, ignoring.", false); return; } Curve = Line.CreateUnbound(pntXYZ, dirXYZ / ParametericScaling); }
override protected void Process(IFCAnyHandle ifcPolyLoop) { base.Process(ifcPolyLoop); List <IFCAnyHandle> ifcPolygon = IFCAnyHandleUtil.GetAggregateInstanceAttribute <List <IFCAnyHandle> >(ifcPolyLoop, "Polygon"); if (ifcPolygon == null) { return; // TODO: WARN } Polygon = IFCPoint.ProcessScaledLengthIFCCartesianPoints(ifcPolygon); int numVertices = Polygon.Count; if (numVertices > 1) { if (Polygon[0].IsAlmostEqualTo(Polygon[numVertices - 1])) { // LOG: Warning: #: First and last points are almost identical, removing extra point. Polygon.RemoveAt(numVertices - 1); numVertices--; } } if (numVertices < 3) { throw new InvalidOperationException("#" + ifcPolyLoop.StepId + ": Polygon attribute has only " + numVertices + " vertices, 3 expected."); } }
// 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 double?GetTrimParameter(IFCData trim, IFCCurve basisCurve, IFCTrimmingPreference trimPreference, bool secondAttempt) { bool preferParam = !(trimPreference == IFCTrimmingPreference.Cartesian); if (secondAttempt) { preferParam = !preferParam; } double vertexEps = MathUtil.VertexEps; IFCAggregate trimAggregate = trim.AsAggregate(); foreach (IFCData trimParam in trimAggregate) { if (!preferParam && (trimParam.PrimitiveType == IFCDataPrimitiveType.Instance)) { IFCAnyHandle trimParamInstance = trimParam.AsInstance(); XYZ trimParamPt = IFCPoint.ProcessScaledLengthIFCCartesianPoint(trimParamInstance); if (trimParamPt == null) { IFCImportFile.TheLog.LogWarning(basisCurve.Id, "Invalid trim point for basis curve.", false); continue; } try { IntersectionResult result = basisCurve.Curve.Project(trimParamPt); if (result.Distance < vertexEps) { return(result.Parameter); } IFCImportFile.TheLog.LogWarning(basisCurve.Id, "Cartesian value for trim point not on the basis curve.", false); } catch { IFCImportFile.TheLog.LogWarning(basisCurve.Id, "Cartesian value for trim point not on the basis curve.", false); } } else if (preferParam && (trimParam.PrimitiveType == IFCDataPrimitiveType.Double)) { double trimParamDouble = trimParam.AsDouble(); if (basisCurve.Curve.IsCyclic) { trimParamDouble = IFCUnitUtil.ScaleAngle(trimParamDouble); } return(trimParamDouble); } } // Try again with opposite preference. if (!secondAttempt) { return(GetTrimParameter(trim, basisCurve, trimPreference, true)); } return(null); }
protected override void Process(IFCAnyHandle ifcVertexPoint) { base.Process(ifcVertexPoint); IFCAnyHandle vertexGeometry = IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcVertexPoint, "VertexGeometry", true); XYZ unScaledVertexGeometry = IFCPoint.ProcessIFCPoint(vertexGeometry); VertexGeometry = IFCUnitUtil.ScaleLength(unScaledVertexGeometry); }
protected override void Process(IFCAnyHandle ifcCurve) { base.Process(ifcCurve); IList <IFCAnyHandle> points = IFCAnyHandleUtil.GetAggregateInstanceAttribute <List <IFCAnyHandle> >(ifcCurve, "Points"); int numPoints = points.Count; if (numPoints < 2) { string msg = "IfcPolyLine had " + numPoints + ", expected at least 2, ignoring"; Importer.TheLog.LogError(Id, msg, false); return; } IList <XYZ> pointXYZs = new List <XYZ>(); foreach (IFCAnyHandle point in points) { XYZ pointXYZ = IFCPoint.ProcessScaledLengthIFCCartesianPoint(point); pointXYZs.Add(pointXYZ); } if (pointXYZs.Count != numPoints) { Importer.TheLog.LogError(Id, "Some of the IFC points cannot be converted to Revit points", true); } CurveLoop = IFCGeometryUtil.CreatePolyCurveLoop(pointXYZs, points, Id, false); if (pointXYZs.Count == 2) { Curve = Line.CreateBound(pointXYZs[0], pointXYZs[1]); } else { // if we go here we are sure that the number of point must be at least 3 XYZ firstPoint = pointXYZs[0]; XYZ secondPoint = pointXYZs[1]; XYZ vectorToTest = (secondPoint - firstPoint).Normalize(); bool allAreCollinear = true; for (int ii = 2; ii < numPoints; ii++) { XYZ vectorTmp = (pointXYZs[ii] - firstPoint).Normalize(); if (!vectorTmp.IsAlmostEqualTo(vectorToTest)) { allAreCollinear = false; break; } } if (allAreCollinear) { Curve = Line.CreateBound(firstPoint, pointXYZs[numPoints - 1]); } } }
protected override void Process(IFCAnyHandle ifcSurface) { base.Process(ifcSurface); bool foundUDegree = false; UDegree = IFCImportHandleUtil.GetRequiredIntegerAttribute(ifcSurface, "UDegree", out foundUDegree); if (!foundUDegree) { Importer.TheLog.LogError(ifcSurface.StepId, "Cannot find the UDegree attribute of this surface", true); } bool foundVDegree = false; VDegree = IFCImportHandleUtil.GetRequiredIntegerAttribute(ifcSurface, "VDegree", out foundVDegree); if (!foundVDegree) { Importer.TheLog.LogError(ifcSurface.StepId, "Cannot find the VDegree attribute of this surface", true); } IList <IList <IFCAnyHandle> > controlPoints = IFCImportHandleUtil.GetListOfListOfInstanceAttribute(ifcSurface, "ControlPointsList"); if (controlPoints == null || controlPoints.Count == 0) { Importer.TheLog.LogError(ifcSurface.StepId, "This surface has invalid number of control points", true); } List <IFCAnyHandle> controlPointsTmp = new List <IFCAnyHandle>(); foreach (List <IFCAnyHandle> list in controlPoints) { controlPointsTmp.AddRange(list); } ControlPointsList = IFCPoint.ProcessScaledLengthIFCCartesianPoints(controlPointsTmp); bool foundUClosed = false; UClosed = IFCImportHandleUtil.GetOptionalLogicalAttribute(ifcSurface, "UClosed", out foundUClosed); if (!foundUClosed) { Importer.TheLog.LogWarning(ifcSurface.StepId, "Cannot find the UClosed attribute of this surface, setting to Unknown", true); UClosed = IFCLogical.Unknown; } bool foundVClosed = false; VClosed = IFCImportHandleUtil.GetOptionalLogicalAttribute(ifcSurface, "VClosed", out foundVClosed); if (!foundVClosed) { Importer.TheLog.LogWarning(ifcSurface.StepId, "Cannot find the VClosed attribute of this surface, setting to Unknown", true); VClosed = IFCLogical.Unknown; } }
static Transform ProcessPlacementBase(IFCAnyHandle placement) { IFCAnyHandle location = IFCAnyHandleUtil.GetInstanceAttribute(placement, "Location"); XYZ origin = IFCPoint.ProcessScaledLengthIFCCartesianPoint(location); if (origin == null) { Importer.TheLog.LogError(placement.StepId, "Missing or invalid location attribute.", false); origin = XYZ.Zero; } return(Transform.CreateTranslation(origin)); }
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); }
static private BoundingBoxXYZ ProcessBoundingBox(IFCAnyHandle boundingBoxHnd) { IFCAnyHandle lowerLeftHnd = IFCAnyHandleUtil.GetInstanceAttribute(boundingBoxHnd, "Corner"); XYZ minXYZ = IFCPoint.ProcessScaledLengthIFCCartesianPoint(lowerLeftHnd); double xDim = IFCAnyHandleUtil.GetDoubleAttribute(boundingBoxHnd, "XDim").Value; double yDim = IFCAnyHandleUtil.GetDoubleAttribute(boundingBoxHnd, "YDim").Value; double zDim = IFCAnyHandleUtil.GetDoubleAttribute(boundingBoxHnd, "ZDim").Value; 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); }
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); } }
static Transform ProcessPlacementBase(IFCAnyHandle placement) { IFCAnyHandle location = IFCAnyHandleUtil.GetInstanceAttribute(placement, "Location"); XYZ origin = IFCPoint.ProcessScaledLengthIFCCartesianPoint(location); if (origin == null) { Importer.TheLog.LogError(placement.StepId, "Missing or invalid location attribute.", false); origin = XYZ.Zero; } else if (FixFarawayLocationOrigin && !XYZ.IsWithinLengthLimits(origin)) { Importer.TheLog.LogError(placement.StepId, "The local placement has an origin that is outside of Revit's creation limits. Moving to the internal origin.", false); origin = XYZ.Zero; } return(Transform.CreateTranslation(origin)); }
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); }
protected override void Process(IFCAnyHandle ifcCurve) { base.Process(ifcCurve); bool foundDegree = false; Degree = IFCImportHandleUtil.GetRequiredIntegerAttribute(ifcCurve, "Degree", out foundDegree); if (!foundDegree) { Importer.TheLog.LogError(ifcCurve.StepId, "Cannot find the degree of this curve", true); } IList <IFCAnyHandle> controlPoints = IFCAnyHandleUtil.GetAggregateInstanceAttribute <List <IFCAnyHandle> >(ifcCurve, "ControlPointsList"); if (controlPoints == null || controlPoints.Count == 0) { Importer.TheLog.LogError(ifcCurve.StepId, "This curve has invalid number of control points", true); } IList <XYZ> controlPointLists = new List <XYZ>(); foreach (IFCAnyHandle point in controlPoints) { XYZ pointXYZ = IFCPoint.ProcessScaledLengthIFCCartesianPoint(point); controlPointLists.Add(pointXYZ); } ControlPointsList = controlPointLists; bool foundClosedCurve = false; IFCLogical closedCurve = IFCImportHandleUtil.GetOptionalLogicalAttribute(ifcCurve, "ClosedCurve", out foundClosedCurve); if (!foundClosedCurve) { Importer.TheLog.LogWarning(ifcCurve.StepId, "Cannot find the ClosedCurve property of this curve, ignoring", false); ClosedCurve = null; } else { ClosedCurve = (closedCurve == IFCLogical.True); } }
private void ProcessIFCPolyline(IFCAnyHandle ifcCurve) { IList <IFCAnyHandle> points = IFCAnyHandleUtil.GetAggregateInstanceAttribute <List <IFCAnyHandle> >(ifcCurve, "Points"); int numPoints = points.Count; if (numPoints < 2) { string msg = "IfcPolyLine had " + numPoints + ", expected at least 2, ignoring"; IFCImportFile.TheLog.LogError(Id, msg, false); return; } IList <XYZ> pointXYZs = new List <XYZ>(); foreach (IFCAnyHandle point in points) { XYZ pointXYZ = IFCPoint.ProcessScaledLengthIFCCartesianPoint(point); pointXYZs.Add(pointXYZ); } CurveLoop = IFCGeometryUtil.CreatePolyCurveLoop(pointXYZs, points, Id, 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 && 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; 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); }
static Transform ProcessPlacementBase(IFCAnyHandle placement) { IFCAnyHandle location = IFCAnyHandleUtil.GetInstanceAttribute(placement, "Location"); return(Transform.CreateTranslation(IFCPoint.ProcessScaledLengthIFCCartesianPoint(location))); }
/// <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 an IfcRepresentationItem entity handle. /// </summary> /// <param name="ifcRepresentationItem">The IfcRepresentationItem handle.</param> /// <returns>The IFCRepresentationItem object.</returns> public static IFCRepresentationItem ProcessIFCRepresentationItem(IFCAnyHandle ifcRepresentationItem) { if (IFCAnyHandleUtil.IsNullOrHasNoValue(ifcRepresentationItem)) { Importer.TheLog.LogNullError(IFCEntityType.IfcRepresentationItem); return(null); } if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcMappedItem)) { return(IFCMappedItem.ProcessIFCMappedItem(ifcRepresentationItem)); } if (IFCImportFile.TheFile.SchemaVersionAtLeast(IFCSchemaVersion.IFC2x2) && IFCAnyHandleUtil.IsSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcStyledItem)) { return(IFCStyledItem.ProcessIFCStyledItem(ifcRepresentationItem)); } if (IFCAnyHandleUtil.IsSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcTopologicalRepresentationItem)) { return(IFCTopologicalRepresentationItem.ProcessIFCTopologicalRepresentationItem(ifcRepresentationItem)); } // TODO: Move everything below to IFCGeometricRepresentationItem, once it is created. if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcBooleanResult)) { return(IFCBooleanResult.ProcessIFCBooleanResult(ifcRepresentationItem)); } if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcCurve)) { return(IFCCurve.ProcessIFCCurve(ifcRepresentationItem)); } if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcFaceBasedSurfaceModel)) { return(IFCFaceBasedSurfaceModel.ProcessIFCFaceBasedSurfaceModel(ifcRepresentationItem)); } if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcGeometricSet)) { return(IFCGeometricSet.ProcessIFCGeometricSet(ifcRepresentationItem)); } if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcPoint)) { return(IFCPoint.ProcessIFCPoint(ifcRepresentationItem)); } if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcShellBasedSurfaceModel)) { return(IFCShellBasedSurfaceModel.ProcessIFCShellBasedSurfaceModel(ifcRepresentationItem)); } if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcSolidModel)) { return(IFCSolidModel.ProcessIFCSolidModel(ifcRepresentationItem)); } // TODO: Move the items below to IFCGeometricRepresentationItem->IFCTessellatedItem->IfcTessellatedFaceSet. if (IFCImportFile.TheFile.SchemaVersionAtLeast(IFCSchemaVersion.IFC4Obsolete) && IFCAnyHandleUtil.IsSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcTriangulatedFaceSet)) { return(IFCTriangulatedFaceSet.ProcessIFCTriangulatedFaceSet(ifcRepresentationItem)); } // There is no way to actually determine an IFC4Add2 file vs. a "vanilla" IFC4 file, which is // obsolete. The try/catch here allows us to read these obsolete files without crashing. try { if (IFCImportFile.TheFile.SchemaVersionAtLeast(IFCSchemaVersion.IFC4) && IFCAnyHandleUtil.IsSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcPolygonalFaceSet)) { return(IFCPolygonalFaceSet.ProcessIFCPolygonalFaceSet(ifcRepresentationItem)); } } catch (Exception ex) { // Once we fail once, downgrade the schema so we don't try again. if (IFCImportFile.HasUndefinedAttribute(ex)) { IFCImportFile.TheFile.DowngradeIFC4SchemaTo(IFCSchemaVersion.IFC4Add1Obsolete); } else { throw ex; } } Importer.TheLog.LogUnhandledSubTypeError(ifcRepresentationItem, IFCEntityType.IfcRepresentationItem, true); return(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); }