/// <summary> /// Creates a simple swept solid from a list of curve loops. /// </summary> /// <param name="exporterIFC">The exporter.</param> /// <param name="profileName">The profile name.</param> /// <param name="profileCurveLoops">The profile curve loops.</param> /// <param name="normal">The normal of the plane that the path lies on.</param> /// <param name="directrix">The path curve.</param> /// <returns>The swept solid handle.</returns> public static IFCAnyHandle CreateSimpleSweptSolid(ExporterIFC exporterIFC, string profileName, IList <CurveLoop> profileCurveLoops, XYZ normal, Curve directrix) { // see definition of IfcSurfaceCurveSweptAreaSolid from // http://www.buildingsmart-tech.org/ifc/IFC2x4/rc4/html/schema/ifcgeometricmodelresource/lexical/ifcsurfacecurvesweptareasolid.htm IFCAnyHandle simpleSweptSolidHnd = null; if (!CanCreateSimpleSweptSolid(profileCurveLoops, normal, directrix)) { return(simpleSweptSolidHnd); } bool isBound = directrix.IsBound; double originalStartParam = isBound ? directrix.GetEndParameter(0) : 0.0; Plane axisPlane, profilePlane; CreateAxisAndProfileCurvePlanes(directrix, originalStartParam, out axisPlane, out profilePlane); IList <CurveLoop> curveLoops = null; try { // Check that curve loops are valid. curveLoops = ExporterIFCUtils.ValidateCurveLoops(profileCurveLoops, profilePlane.Normal); } catch (Exception) { return(null); } if (curveLoops == null || curveLoops.Count == 0) { return(simpleSweptSolidHnd); } double startParam = 0.0, endParam = 1.0; if (directrix is Arc) { // This effectively resets the start parameter to 0.0, and end parameter = length of curve. if (isBound) { endParam = UnitUtil.ScaleAngle(MathUtil.PutInRange(directrix.GetEndParameter(1), Math.PI, 2 * Math.PI) - MathUtil.PutInRange(originalStartParam, Math.PI, 2 * Math.PI)); } else { endParam = 2.0 * Math.PI; } } // Start creating IFC entities. IFCAnyHandle sweptArea = ExtrusionExporter.CreateSweptArea(exporterIFC, profileName, curveLoops, profilePlane, profilePlane.Normal); if (IFCAnyHandleUtil.IsNullOrHasNoValue(sweptArea)) { return(simpleSweptSolidHnd); } IFCAnyHandle curveHandle = null; IFCAnyHandle referenceSurfaceHandle = ExtrusionExporter.CreateSurfaceOfLinearExtrusionFromCurve(exporterIFC, directrix, axisPlane, 1.0, 1.0, out curveHandle); // Should this be moved up? Check. Plane scaledAxisPlane = GeometryUtil.GetScaledPlane(exporterIFC, axisPlane); IFCFile file = exporterIFC.GetFile(); IFCAnyHandle solidAxis = ExporterUtil.CreateAxis(file, scaledAxisPlane.Origin, scaledAxisPlane.Normal, scaledAxisPlane.XVec); simpleSweptSolidHnd = IFCInstanceExporter.CreateSurfaceCurveSweptAreaSolid(file, sweptArea, solidAxis, curveHandle, startParam, endParam, referenceSurfaceHandle); return(simpleSweptSolidHnd); }
/// <summary> /// Creates a simple swept solid from a list of curve loops. /// </summary> /// <param name="exporterIFC">The exporter.</param> /// <param name="profileName">The profile name.</param> /// <param name="profileCurveLoops">The profile curve loops.</param> /// <param name="normal">The normal of the plane that the path lies on.</param> /// <param name="directrix">The path curve.</param> /// <returns>The swept solid handle.</returns> public static IFCAnyHandle CreateSimpleSweptSolid(ExporterIFC exporterIFC, string profileName, IList <CurveLoop> profileCurveLoops, XYZ normal, Curve directrix) { // see definition of IfcSurfaceCurveSweptAreaSolid from // http://www.buildingsmart-tech.org/ifc/IFC2x4/rc4/html/schema/ifcgeometricmodelresource/lexical/ifcsurfacecurvesweptareasolid.htm IFCAnyHandle simpleSweptSolidHnd = null; if (!CanCreateSimpleSweptSolid(profileCurveLoops, normal, directrix)) { return(simpleSweptSolidHnd); } bool isBound = directrix.IsBound; double originalStartParam = isBound ? directrix.GetEndParameter(0) : 0.0; Transform axisLCS, profileLCS; CreateAxisAndProfileCurveLCS(directrix, originalStartParam, out axisLCS, out profileLCS); IList <CurveLoop> curveLoops = null; try { // Check that curve loops are valid. curveLoops = ExporterIFCUtils.ValidateCurveLoops(profileCurveLoops, profileLCS.BasisZ); } catch (Exception) { return(null); } if (curveLoops == null || curveLoops.Count == 0) { return(simpleSweptSolidHnd); } double startParam = 0.0, endParam = 1.0; if (directrix is Arc) { // This effectively resets the start parameter to 0.0, and end parameter = length of curve. if (isBound) { // Put the parameters in range of [0, 2*Pi] double inRangeStarParam = (directrix.GetEndParameter(0) % (2 * Math.PI)); double inRangeEndParam = (directrix.GetEndParameter(1) % (2 * Math.PI)); // We want the angle direction is anti-clockwise (+ direction), therefore we will always start with the smaller one if (inRangeEndParam < inRangeStarParam) { double tmp = inRangeStarParam; inRangeStarParam = inRangeEndParam; inRangeEndParam = tmp; } // If start param is negative, we will reset it to 0 and shift the end accordingly if (inRangeStarParam < 0) { double parRange = inRangeEndParam - inRangeStarParam; inRangeStarParam = 0.0; inRangeEndParam = parRange; } endParam = UnitUtil.ScaleAngle(inRangeEndParam); //endParam = UnitUtil.ScaleAngle(MathUtil.PutInRange(directrix.GetEndParameter(1), Math.PI, 2 * Math.PI) - // MathUtil.PutInRange(originalStartParam, Math.PI, 2 * Math.PI)); } else { endParam = 2.0 * Math.PI; } } // Start creating IFC entities. IFCAnyHandle sweptArea = ExtrusionExporter.CreateSweptArea(exporterIFC, profileName, curveLoops, profileLCS, profileLCS.BasisZ); if (IFCAnyHandleUtil.IsNullOrHasNoValue(sweptArea)) { return(simpleSweptSolidHnd); } IFCAnyHandle curveHandle = null; IFCAnyHandle referenceSurfaceHandle = ExtrusionExporter.CreateSurfaceOfLinearExtrusionFromCurve(exporterIFC, directrix, axisLCS, 1.0, 1.0, out curveHandle); // Should this be moved up? Check. XYZ scaledOrigin = ExporterIFCUtils.TransformAndScalePoint(exporterIFC, axisLCS.Origin); XYZ scaledXDir = ExporterIFCUtils.TransformAndScaleVector(exporterIFC, axisLCS.BasisX).Normalize(); XYZ scaledNormal = ExporterIFCUtils.TransformAndScaleVector(exporterIFC, axisLCS.BasisZ).Normalize(); IFCFile file = exporterIFC.GetFile(); IFCAnyHandle solidAxis = ExporterUtil.CreateAxis(file, scaledOrigin, scaledNormal, scaledXDir); simpleSweptSolidHnd = IFCInstanceExporter.CreateSurfaceCurveSweptAreaSolid(file, sweptArea, solidAxis, curveHandle, startParam, endParam, referenceSurfaceHandle); return(simpleSweptSolidHnd); }