Beispiel #1
0
        protected List <GeometryObject> CreateConformalGeometryIfPossible(
            IFCImportShapeEditScope shapeEditScope, Transform unscaledLcs)
        {
            Transform unscaledSweptDiskPosition = (unscaledLcs == null) ? Transform.Identity : unscaledLcs;

            IList <CurveLoop> trimmedDirectrices = IFCGeometryUtil.TrimCurveLoops(Id, Directrix, StartParameter, EndParameter);

            if (trimmedDirectrices == null)
            {
                return(null);
            }

            List <GeometryObject> myObjs = null;
            bool isIdentity = unscaledSweptDiskPosition.IsIdentity;

            foreach (CurveLoop trimmedDirectrix in trimmedDirectrices)
            {
                // Create the disk.
                Curve firstCurve = null;
                foreach (Curve curve in trimmedDirectrix)
                {
                    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);
                myObjs = new List <GeometryObject>();

                try
                {
                    Solid sweptDiskSolid = GeometryCreationUtilities.CreateSweptGeometry(trimmedDirectrix, 0, startParam, profileCurveLoops,
                                                                                         solidOptions);
                    if (!isIdentity)
                    {
                        sweptDiskSolid = SolidUtils.CreateTransformed(sweptDiskSolid, unscaledSweptDiskPosition);
                    }

                    if (sweptDiskSolid != null)
                    {
                        myObjs.Add(sweptDiskSolid);
                    }
                }
                catch
                {
                    return(null);
                }
            }

            return(myObjs);
        }
Beispiel #2
0
        /// <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);

            IList <CurveLoop> trimmedDirectrices = IFCGeometryUtil.TrimCurveLoops(Id, Directrix, StartParameter, EndParameter);

            if (trimmedDirectrices == null)
            {
                return(null);
            }

            IList <GeometryObject> myObjs = null;

            foreach (CurveLoop trimmedDirectrix in trimmedDirectrices)
            {
                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);
                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);
        }
Beispiel #3
0
        /// <summary>
        /// Return geometry for a particular representation item.
        /// </summary>
        /// <param name="shapeEditScope">The geometry creation scope.</param>
        /// <param name="unscaledLcs">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 unscaledLcs, Transform scaledLcs, string guid)
        {
            List <GeometryObject> myObjs = null;

            if (scaledLcs == null || scaledLcs.IsConformal && MathUtil.IsAlmostEqual(scaledLcs.Scale, 1.0))
            {
                myObjs = CreateConformalGeometryIfPossible(shapeEditScope, unscaledLcs);
                if (myObjs != null)
                {
                    return(myObjs);
                }
            }

            Transform unscaledSweptDiskPosition = (unscaledLcs == null) ? Transform.Identity : unscaledLcs;
            Transform scaledSweptDiskPosition   = (scaledLcs == null) ? Transform.Identity : scaledLcs;

            IList <CurveLoop> trimmedDirectrices = IFCGeometryUtil.TrimCurveLoops(Id, Directrix, StartParameter, EndParameter);

            if (trimmedDirectrices == null)
            {
                return(null);
            }

            foreach (CurveLoop trimmedDirectrix in trimmedDirectrices)
            {
                CurveLoop trimmedDirectrixInWCS = IFCGeometryUtil.CreateTransformed(trimmedDirectrix, Id, unscaledSweptDiskPosition, scaledSweptDiskPosition);

                // 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);
                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") || ex.Message.Contains("Failed to create"))
                    {
                        (IList <GeometryObject>, bool)solidSegments = SplitSweptDiskIntoValidPieces(trimmedDirectrixInWCS, profileCurveLoops, solidOptions);
                        if (solidSegments.Item1 != null)
                        {
                            myObjs.AddRange(solidSegments.Item1);
                        }

                        // If Item2 is true, that means that the backup SplitSweptDiskIntoValidPieces routine was
                        // able to create (probably slightly self-intersecting) geometry for all of the pieces
                        // of the directrix.  If it is false, then there was some part of the directrix that we
                        // couldn't create geometry for.  Log a warning in the first case and an error in the
                        // second.
                        if (solidSegments.Item2)
                        {
                            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);
                        }
                        else
                        {
                            Importer.TheLog.LogError(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 as much of the geometry as possible.", false);
                        }
                    }
                    else
                    {
                        throw ex;
                    }
                }
            }

            return(myObjs);
        }
Beispiel #4
0
        /// <summary>
        /// Return geometry for a particular representation item.
        /// </summary>
        /// <param name="shapeEditScope">The geometry creation scope.</param>
        /// <param name="unscaledLcs">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 unscaledLcs, Transform scaledLcs, string guid)
        {
            Transform unscaledSweptDiskPosition = (unscaledLcs == null) ? Transform.Identity : unscaledLcs;
            Transform scaledSweptDiskPosition   = (scaledLcs == null) ? Transform.Identity : scaledLcs;

            IList <CurveLoop> trimmedDirectrices = IFCGeometryUtil.TrimCurveLoops(Id, Directrix, StartParameter, EndParameter);

            if (trimmedDirectrices == null)
            {
                return(null);
            }

            List <GeometryObject> myObjs = null;

            foreach (CurveLoop trimmedDirectrix in trimmedDirectrices)
            {
                CurveLoop trimmedDirectrixInWCS = IFCGeometryUtil.CreateTransformed(trimmedDirectrix, Id, unscaledSweptDiskPosition, scaledSweptDiskPosition);

                // 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);
                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.AddRange(SplitSweptDiskIntoValidPieces(trimmedDirectrixInWCS, profileCurveLoops, solidOptions));
                    }
                    else
                    {
                        throw ex;
                    }
                }
            }

            return(myObjs);
        }