/// <summary> /// Return geometry for a particular representation item. /// </summary> /// <param name="shapeEditScope">The geometry creation scope.</param> /// <param name="unscaledLcs">The unscaled local coordinate system for the geometry, if the scaled version isn't supported downstream.</param> /// <param name="scaledLcs">The scaled (true) local coordinate system for the geometry.</param> /// <param name="guid">The guid of an element for which represntation is being created.</param> /// <returns>The created geometry.</returns> protected override IList <GeometryObject> CreateGeometryInternal( IFCImportShapeEditScope shapeEditScope, Transform unscaledLcs, Transform scaledLcs, string guid) { Transform unscaledObjectPosition = (unscaledLcs == null) ? Position : unscaledLcs.Multiply(Position); Transform scaledObjectPosition = (scaledLcs == null) ? Position : scaledLcs.Multiply(Position); CurveLoop baseProfileCurve = Directrix.GetCurveLoop(); if (baseProfileCurve == null) { return(null); } CurveLoop trimmedDirectrix = IFCGeometryUtil.TrimCurveLoop(Id, baseProfileCurve, StartParameter, EndParameter); if (trimmedDirectrix == null) { return(null); } double startParam = 0.0; // If the directrix isn't bound, this arbitrary parameter will do. Transform originTrf0 = null; Curve firstCurve0 = trimmedDirectrix.First(); if (firstCurve0.IsBound) { startParam = firstCurve0.GetEndParameter(0); } originTrf0 = firstCurve0.ComputeDerivatives(startParam, false); if (originTrf0 == null) { return(null); } // Note: the computation of the reference Surface Local Transform must be done before the directrix is transform to LCS (because the ref surface isn't) // and therefore the origin is at the start of the curve should be the start of the directrix that lies on the surface. // This is needed to transform the swept area that must be perpendicular to the start of the directrix curve Transform referenceSurfaceLocalTransform = ReferenceSurface.GetTransformAtPoint(originTrf0.Origin); CurveLoop trimmedDirectrixInLCS = IFCGeometryUtil.CreateTransformed(trimmedDirectrix, Id, unscaledObjectPosition, scaledObjectPosition); // Create the sweep. Transform originTrf = null; Curve firstCurve = trimmedDirectrixInLCS.First(); //if (firstCurve.IsBound) // startParam = firstCurve.GetEndParameter(0); originTrf = firstCurve.ComputeDerivatives(startParam, false); Transform unscaledReferenceSurfaceTransform = unscaledObjectPosition.Multiply(referenceSurfaceLocalTransform); Transform scaledReferenceSurfaceTransform = scaledObjectPosition.Multiply(referenceSurfaceLocalTransform); Transform profileCurveLoopsTransform = Transform.CreateTranslation(originTrf.Origin); profileCurveLoopsTransform.BasisX = scaledReferenceSurfaceTransform.BasisZ; profileCurveLoopsTransform.BasisZ = originTrf.BasisX.Normalize(); profileCurveLoopsTransform.BasisY = profileCurveLoopsTransform.BasisZ.CrossProduct(profileCurveLoopsTransform.BasisX); ISet <IList <CurveLoop> > profileCurveLoops = GetTransformedCurveLoops(profileCurveLoopsTransform, profileCurveLoopsTransform); if (profileCurveLoops == null || profileCurveLoops.Count == 0) { return(null); } SolidOptions solidOptions = new SolidOptions(GetMaterialElementId(shapeEditScope), shapeEditScope.GraphicsStyleId); IList <GeometryObject> myObjs = new List <GeometryObject>(); foreach (IList <CurveLoop> loops in profileCurveLoops) { GeometryObject myObj = GeometryCreationUtilities.CreateSweptGeometry(trimmedDirectrixInLCS, 0, startParam, loops, solidOptions); if (myObj != null) { myObjs.Add(myObj); } } return(myObjs); }
/// <summary> /// Return geometry for a particular representation item. /// </summary> /// <param name="shapeEditScope">The geometry creation scope.</param> /// <param name="lcs">Local coordinate system for the geometry.</param> /// <param name="guid">The guid of an element for which represntation is being created.</param> /// <returns>The created geometry.</returns> protected override IList <GeometryObject> CreateGeometryInternal( IFCImportShapeEditScope shapeEditScope, Transform lcs, Transform scaledLcs, string guid) { Transform objectPosition = (lcs == null) ? Position : lcs.Multiply(Position); CurveLoop baseProfileCurve = Directrix.GetCurveLoop(); if (baseProfileCurve == null) { return(null); } CurveLoop trimmedDirectrix = IFCGeometryUtil.TrimCurveLoop(baseProfileCurve, StartParameter, EndParameter); if (trimmedDirectrix == null) { return(null); } CurveLoop trimmedDirectrixInLCS = IFCGeometryUtil.CreateTransformed(trimmedDirectrix, objectPosition); // Create the sweep. double startParam = 0.0; // If the directrix isn't bound, this arbitrary parameter will do. Transform originTrf = null; Curve firstCurve = trimmedDirectrixInLCS.First(); if (firstCurve.IsBound) { startParam = firstCurve.GetEndParameter(0); } originTrf = firstCurve.ComputeDerivatives(startParam, false); if (originTrf == null) { return(null); } Transform referenceSurfaceLocalTransform = ReferenceSurface.GetTransformAtPoint(originTrf.Origin); Transform referenceSurfaceTransform = objectPosition.Multiply(referenceSurfaceLocalTransform); Transform profileCurveLoopsTransform = Transform.CreateTranslation(originTrf.Origin); profileCurveLoopsTransform.BasisX = referenceSurfaceTransform.BasisZ; profileCurveLoopsTransform.BasisZ = originTrf.BasisX.Normalize(); profileCurveLoopsTransform.BasisY = profileCurveLoopsTransform.BasisZ.CrossProduct(profileCurveLoopsTransform.BasisX); ISet <IList <CurveLoop> > profileCurveLoops = GetTransformedCurveLoops(profileCurveLoopsTransform); if (profileCurveLoops == null || profileCurveLoops.Count == 0) { return(null); } SolidOptions solidOptions = new SolidOptions(GetMaterialElementId(shapeEditScope), shapeEditScope.GraphicsStyleId); IList <GeometryObject> myObjs = new List <GeometryObject>(); foreach (IList <CurveLoop> loops in profileCurveLoops) { GeometryObject myObj = GeometryCreationUtilities.CreateSweptGeometry(trimmedDirectrixInLCS, 0, startParam, loops, solidOptions); if (myObj != null) { myObjs.Add(myObj); } } return(myObjs); }
/// <summary> /// Return geometry for a particular representation item. /// </summary> /// <param name="shapeEditScope">The geometry creation scope.</param> /// <param name="lcs">Local coordinate system for the geometry, without scale.</param> /// <param name="scaledLcs">Local coordinate system for the geometry, including scale, potentially non-uniform.</param> /// <param name="guid">The guid of an element for which represntation is being created.</param> /// <returns>Zero or more created geometries.</returns> protected override IList <GeometryObject> CreateGeometryInternal( IFCImportShapeEditScope shapeEditScope, Transform lcs, Transform scaledLcs, string guid) { Transform sweptDiskPosition = (lcs == null) ? Transform.Identity : lcs; CurveLoop baseProfileCurve = Directrix.GetCurveLoop(); if (baseProfileCurve == null) { return(null); } CurveLoop trimmedDirectrix = IFCGeometryUtil.TrimCurveLoop(baseProfileCurve, StartParameter, EndParameter); if (trimmedDirectrix == null) { return(null); } CurveLoop trimmedDirectrixInLCS = IFCGeometryUtil.CreateTransformed(trimmedDirectrix, sweptDiskPosition); // Create the disk. Transform originTrf = null; double startParam = 0.0; // If the directrix isn't bound, this arbitrary parameter will do. foreach (Curve curve in trimmedDirectrixInLCS) { if (curve.IsBound) { startParam = curve.GetEndParameter(0); } originTrf = curve.ComputeDerivatives(startParam, false); break; } if (originTrf == null) { return(null); } // The X-dir of the transform of the start of the directrix will form the normal of the disk. Plane diskPlane = new Plane(originTrf.BasisX, originTrf.Origin); IList <CurveLoop> profileCurveLoops = new List <CurveLoop>(); CurveLoop diskOuterCurveLoop = new CurveLoop(); diskOuterCurveLoop.Append(Arc.Create(diskPlane, Radius, 0, Math.PI)); diskOuterCurveLoop.Append(Arc.Create(diskPlane, Radius, Math.PI, 2.0 * Math.PI)); profileCurveLoops.Add(diskOuterCurveLoop); if (InnerRadius.HasValue) { CurveLoop diskInnerCurveLoop = new CurveLoop(); diskInnerCurveLoop.Append(Arc.Create(diskPlane, InnerRadius.Value, 0, Math.PI)); diskInnerCurveLoop.Append(Arc.Create(diskPlane, InnerRadius.Value, Math.PI, 2.0 * Math.PI)); profileCurveLoops.Add(diskInnerCurveLoop); } SolidOptions solidOptions = new SolidOptions(GetMaterialElementId(shapeEditScope), shapeEditScope.GraphicsStyleId); Solid sweptDiskSolid = GeometryCreationUtilities.CreateSweptGeometry(trimmedDirectrixInLCS, 0, startParam, profileCurveLoops, solidOptions); IList <GeometryObject> myObjs = new List <GeometryObject>(); if (sweptDiskSolid != null) { myObjs.Add(sweptDiskSolid); } return(myObjs); }
/// <summary> /// Return geometry for a particular representation item. /// </summary> /// <param name="shapeEditScope">The geometry creation scope.</param> /// <param name="lcs">Local coordinate system for the geometry, without scale.</param> /// <param name="scaledLcs">Local coordinate system for the geometry, including scale, potentially non-uniform.</param> /// <param name="guid">The guid of an element for which represntation is being created.</param> /// <returns>Zero or more created geometries.</returns> protected override IList <GeometryObject> CreateGeometryInternal( IFCImportShapeEditScope shapeEditScope, Transform lcs, Transform scaledLcs, string guid) { Transform sweptDiskPosition = (lcs == null) ? Transform.Identity : lcs; CurveLoop baseProfileCurve = Directrix.GetCurveLoop(); if (baseProfileCurve == null) { return(null); } CurveLoop trimmedDirectrix = IFCGeometryUtil.TrimCurveLoop(baseProfileCurve, StartParameter, EndParameter); if (trimmedDirectrix == null) { return(null); } CurveLoop trimmedDirectrixInWCS = IFCGeometryUtil.CreateTransformed(trimmedDirectrix, sweptDiskPosition); // Create the disk. Curve firstCurve = null; foreach (Curve curve in trimmedDirectrixInWCS) { firstCurve = curve; break; } double startParam = 0.0; IList <CurveLoop> profileCurveLoops = CreateProfileCurveLoopsForDirectrix(firstCurve, out startParam); if (profileCurveLoops == null) { return(null); } SolidOptions solidOptions = new SolidOptions(GetMaterialElementId(shapeEditScope), shapeEditScope.GraphicsStyleId); IList <GeometryObject> myObjs = new List <GeometryObject>(); try { Solid sweptDiskSolid = GeometryCreationUtilities.CreateSweptGeometry(trimmedDirectrixInWCS, 0, startParam, profileCurveLoops, solidOptions); if (sweptDiskSolid != null) { myObjs.Add(sweptDiskSolid); } } catch (Exception ex) { // If we can't create a solid, we will attempt to split the Solid into valid pieces (that will likely have some overlap). if (ex.Message.Contains("self-intersections")) { Importer.TheLog.LogWarning(Id, "The IfcSweptDiskSolid definition does not define a valid solid, likely due to self-intersections or other such problems; the profile probably extends too far toward the inner curvature of the sweep path. Creating the minimum number of solids possible to represent the geometry.", false); myObjs = SplitSweptDiskIntoValidPieces(trimmedDirectrixInWCS, profileCurveLoops, solidOptions); } else { throw ex; } } return(myObjs); }