private IList <CurveLoop> GetTransformedCurveLoopsFromSimpleProfile(IFCSimpleProfile simpleSweptArea, Transform unscaledLcs, Transform scaledLcs) { IList <CurveLoop> loops = new List <CurveLoop>(); // It is legal for simpleSweptArea.Position to be null, for example for IfcArbitraryClosedProfileDef. Transform unscaledSweptAreaPosition = (simpleSweptArea.Position == null) ? unscaledLcs : unscaledLcs.Multiply(simpleSweptArea.Position); Transform scaledSweptAreaPosition = (simpleSweptArea.Position == null) ? scaledLcs : scaledLcs.Multiply(simpleSweptArea.Position); CurveLoop currLoop = simpleSweptArea.OuterCurve; if (currLoop == null || currLoop.Count() == 0) { Importer.TheLog.LogError(simpleSweptArea.Id, "No outer curve loop for profile, ignoring.", false); return(null); } currLoop = IFCGeometryUtil.SplitUnboundCyclicCurves(currLoop); loops.Add(IFCGeometryUtil.CreateTransformed(currLoop, Id, unscaledSweptAreaPosition, scaledSweptAreaPosition)); if (simpleSweptArea.InnerCurves != null) { foreach (CurveLoop innerCurveLoop in simpleSweptArea.InnerCurves) { loops.Add(IFCGeometryUtil.CreateTransformed(IFCGeometryUtil.SplitUnboundCyclicCurves(innerCurveLoop), Id, unscaledSweptAreaPosition, scaledSweptAreaPosition)); } } return(loops); }
/// <summary> /// Add curves to represent the plan view of the created object. /// </summary> /// <param name="curves">The list of curves, to be validated.</param> /// <param name="id">The id of the object being created, for error logging.</param> /// <returns>True if any curves were added to the plan view representation.</returns> public bool AddPlanViewCurves(IList <Curve> curves, int id) { ViewShapeBuilder = null; int numCurves = curves.Count; if (numCurves > 0) { ViewShapeBuilder = new ViewShapeBuilder(DirectShapeTargetViewType.Plan); IFCGeometryUtil.SplitUnboundCyclicCurves(curves); // Ideally we'd form these curves into a CurveLoop and get the Plane of the CurveLoop. However, there is no requirement // that the plan view curves form one contiguous loop. foreach (Curve curve in curves) { if (ViewShapeBuilder.ValidateCurve(curve)) { ViewShapeBuilder.AddCurve(curve); } else { // We will move the origin to Z=0 if necessary, since the VSB requires all curves to be in the Z=0 plane. // This only works if the curves are in a plane parallel to the Z=0 plane. // NOTE: We could instead project the curves to the Z=0 plane, which could have the effect of changing their geometry. // Until we see such cases, we will take the easier route here. try { // If the end points aren't equal in Z, then the curve isn't parallel to Z. bool isBound = curve.IsBound; XYZ startPoint = isBound ? curve.GetEndPoint(0) : curve.Evaluate(0, false); XYZ endPoint = isBound ? curve.GetEndPoint(1) : startPoint; if (!MathUtil.IsAlmostEqual(startPoint.Z, endPoint.Z)) { throw new InvalidOperationException("Non-planar curve in footprint representation."); } // Lines won't have a non-zero BasisZ value, so don't bother computing. if (!(curve is Line)) { Transform coordinatePlane = curve.ComputeDerivatives(0, true); if (coordinatePlane != null && coordinatePlane.BasisZ != null && !coordinatePlane.BasisZ.IsZeroLength()) { XYZ normalizedZ = coordinatePlane.BasisZ.Normalize(); if (!MathUtil.IsAlmostEqual(Math.Abs(normalizedZ.Z), 1.0)) { throw new InvalidOperationException("Non-planar curve in footprint representation."); } } } // We expect startPoint.Z to be non-zero, otherwise ValidateCurve would have accepted the curve in the first place. Transform offsetTransform = Transform.CreateTranslation(-startPoint.Z * XYZ.BasisZ); Curve projectedCurve = curve.CreateTransformed(offsetTransform); // We may have missed a case above - for example, a curve whose end points have the same Z value, and whose normal at the // start point is in +/-Z, but is regardless non-planar. ValidateCurve has a final chance to reject such curves here. if (projectedCurve == null || !ViewShapeBuilder.ValidateCurve(projectedCurve)) { throw new InvalidOperationException("Invalid curve in footprint representation."); } ViewShapeBuilder.AddCurve(projectedCurve); continue; } catch { } Importer.TheLog.LogError(id, "Invalid curve in FootPrint representation, ignoring.", false); numCurves--; } } if (numCurves == 0) { ViewShapeBuilder = null; } } return(ViewShapeBuilder != null); }