Ejemplo n.º 1
0
        /// <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>The created geometry.</returns>
        public IList <GeometryObject> CreateGeometry(
            IFCImportShapeEditScope shapeEditScope, Transform lcs, Transform scaledLcs, string guid)
        {
            IList <GeometryObject> firstSolids = FirstOperand.CreateGeometry(shapeEditScope, lcs, scaledLcs, guid);

            if (firstSolids != null)
            {
                foreach (GeometryObject potentialSolid in firstSolids)
                {
                    if (!(potentialSolid is Solid))
                    {
                        Importer.TheLog.LogError((FirstOperand as IFCRepresentationItem).Id, "Can't perform Boolean operation on a Mesh.", false);
                        return(firstSolids);
                    }
                }
            }

            IList <GeometryObject> secondSolids = null;

            if (SecondOperand != null)
            {
                try
                {
                    using (IFCImportShapeEditScope.BuildPreferenceSetter setter =
                               new IFCImportShapeEditScope.BuildPreferenceSetter(shapeEditScope, IFCImportShapeEditScope.BuildPreferenceType.ForceSolid))
                    {
                        // Before we process the second operand, we are going to see if there is a uniform material set for the first operand
                        // (corresponding to the solid in the Boolean operation).  We will try to suggest the same material for the voids to avoid arbitrary
                        // setting of material information for the cut faces.
                        IFCStyledItem firstOperandStyledItem = GetStyledItemFromOperand(FirstOperand as IFCRepresentationItem);
                        using (IFCImportShapeEditScope.IFCMaterialStack stack =
                                   new IFCImportShapeEditScope.IFCMaterialStack(shapeEditScope, firstOperandStyledItem, null))
                        {
                            secondSolids = SecondOperand.CreateGeometry(shapeEditScope, lcs, scaledLcs, guid);
                        }
                    }
                }
                catch (Exception ex)
                {
                    // We will allow something to be imported, in the case where the second operand is invalid.
                    // If the first (base) operand is invalid, we will still fail the import of this solid.
                    if (SecondOperand is IFCRepresentationItem)
                    {
                        Importer.TheLog.LogError((SecondOperand as IFCRepresentationItem).Id, ex.Message, false);
                    }
                    else
                    {
                        throw ex;
                    }
                    secondSolids = null;
                }
            }

            IList <GeometryObject> resultSolids = null;

            if (firstSolids == null)
            {
                resultSolids = secondSolids;
            }
            else if (secondSolids == null || BooleanOperator == null)
            {
                if (BooleanOperator == null)
                {
                    Importer.TheLog.LogError(Id, "Invalid BooleanOperationsType.", false);
                }
                resultSolids = firstSolids;
            }
            else
            {
                BooleanOperationsType booleanOperationsType = BooleanOperationsType.Difference;
                switch (BooleanOperator)
                {
                case IFCBooleanOperator.Difference:
                    booleanOperationsType = BooleanOperationsType.Difference;
                    break;

                case IFCBooleanOperator.Intersection:
                    booleanOperationsType = BooleanOperationsType.Intersect;
                    break;

                case IFCBooleanOperator.Union:
                    booleanOperationsType = BooleanOperationsType.Union;
                    break;

                default:
                    Importer.TheLog.LogError(Id, "Invalid BooleanOperationsType.", true);
                    break;
                }

                resultSolids = new List <GeometryObject>();
                foreach (GeometryObject firstSolid in firstSolids)
                {
                    Solid resultSolid = (firstSolid as Solid);

                    int secondId = (SecondOperand == null) ? -1 : (SecondOperand as IFCRepresentationItem).Id;
                    XYZ suggestedShiftDirection = (SecondOperand == null) ? null : SecondOperand.GetSuggestedShiftDirection(lcs);
                    foreach (GeometryObject secondSolid in secondSolids)
                    {
                        resultSolid = IFCGeometryUtil.ExecuteSafeBooleanOperation(Id, secondId, resultSolid, secondSolid as Solid, booleanOperationsType, suggestedShiftDirection);
                        if (resultSolid == null)
                        {
                            break;
                        }
                    }

                    if (resultSolid != null)
                    {
                        resultSolids.Add(resultSolid);
                    }
                }
            }

            return(resultSolids);
        }
Ejemplo n.º 2
0
        /// <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>The created geometry.</returns>
        public IList <GeometryObject> CreateGeometry(
            IFCImportShapeEditScope shapeEditScope, Transform lcs, Transform scaledLcs, string guid)
        {
            IList <GeometryObject> firstSolids = FirstOperand.CreateGeometry(shapeEditScope, lcs, scaledLcs, guid);

            if (firstSolids != null)
            {
                foreach (GeometryObject potentialSolid in firstSolids)
                {
                    if (!(potentialSolid is Solid))
                    {
                        IFCImportFile.TheLog.LogError((FirstOperand as IFCRepresentationItem).Id, "Can't perform Boolean operation on a Mesh.", false);
                        return(firstSolids);
                    }
                }
            }

            IList <GeometryObject> secondSolids = null;

            if (SecondOperand != null)
            {
                try
                {
                    using (IFCImportShapeEditScope.IFCTargetSetter setter =
                               new IFCImportShapeEditScope.IFCTargetSetter(shapeEditScope, TessellatedShapeBuilderTarget.Solid, TessellatedShapeBuilderFallback.Abort))
                    {
                        secondSolids = SecondOperand.CreateGeometry(shapeEditScope, lcs, scaledLcs, guid);
                    }
                }
                catch (Exception ex)
                {
                    // We will allow something to be imported, in the case where the second operand is invalid.
                    // If the first (base) operand is invalid, we will still fail the import of this solid.
                    if (SecondOperand is IFCRepresentationItem)
                    {
                        IFCImportFile.TheLog.LogError((SecondOperand as IFCRepresentationItem).Id, ex.Message, false);
                    }
                    else
                    {
                        throw ex;
                    }
                    secondSolids = null;
                }
            }

            IList <GeometryObject> resultSolids = null;

            if (firstSolids == null)
            {
                resultSolids = secondSolids;
            }
            else if (secondSolids == null)
            {
                resultSolids = firstSolids;
            }
            else
            {
                BooleanOperationsType booleanOperationsType = BooleanOperationsType.Difference;
                switch (BooleanOperator)
                {
                case IFCBooleanOperator.Difference:
                    booleanOperationsType = BooleanOperationsType.Difference;
                    break;

                case IFCBooleanOperator.Intersection:
                    booleanOperationsType = BooleanOperationsType.Intersect;
                    break;

                case IFCBooleanOperator.Union:
                    booleanOperationsType = BooleanOperationsType.Union;
                    break;

                default:
                    IFCImportFile.TheLog.LogError(Id, "Invalid BooleanOperationsType.", true);
                    break;
                }

                resultSolids = new List <GeometryObject>();
                foreach (GeometryObject firstSolid in firstSolids)
                {
                    Solid resultSolid = (firstSolid as Solid);

                    int secondId = (SecondOperand == null) ? -1 : (SecondOperand as IFCRepresentationItem).Id;
                    foreach (GeometryObject secondSolid in secondSolids)
                    {
                        resultSolid = IFCGeometryUtil.ExecuteSafeBooleanOperation(Id, secondId, resultSolid, secondSolid as Solid, booleanOperationsType);
                        if (resultSolid == null)
                        {
                            break;
                        }
                    }

                    if (resultSolid != null)
                    {
                        resultSolids.Add(resultSolid);
                    }
                }
            }

            return(resultSolids);
        }