Ejemplo n.º 1
0
        private string CalculateDoorOperationStyle(FamilyInstance currElem)
        {
            const double smallAngle = Math.PI / 36;

            if (currElem == null)
            {
                return("NOTDEFINED");
            }

            FamilySymbol famSymbol = currElem.Symbol;

            if (famSymbol == null)
            {
                return("NOTDEFINED");
            }
            Family fam = famSymbol.Family;

            if (fam == null)
            {
                return("NOTDEFINED");
            }

            IList <Arc> origArcs = ExporterIFCUtils.GetDoor2DArcsFromFamily(fam);

            if (origArcs == null || (origArcs.Count == 0))
            {
                return("NOTDEFINED");
            }

            IList <Arc>    filteredArcs = new List <Arc>();
            IList <bool>   flippedArcs  = new List <bool>();
            IList <double> offsetAngles = new List <double>();

            foreach (Arc arc in origArcs)
            {
                XYZ zVec = arc.Normal;
                if (!MathUtil.IsAlmostEqual(Math.Abs(zVec.Z), 1.0))
                {
                    continue;
                }

                double angleOffOfXY = 0;
                bool   flipped      = false;

                if (arc.IsBound)
                {
                    flipped = MathUtil.IsAlmostEqual(Math.Abs(zVec.Z), -1.0);
                    XYZ xVec = flipped ? -arc.XDirection : arc.XDirection;
                    angleOffOfXY = Math.Atan2(xVec.Y, xVec.X);
                }

                filteredArcs.Add(arc);
                flippedArcs.Add(flipped);
                offsetAngles.Add(angleOffOfXY);
            }

            int numArcs = filteredArcs.Count;

            if (numArcs == 0)
            {
                return("NOTDEFINED");
            }

            double angleEps = ExporterCacheManager.Document.Application.AngleTolerance;

            if (numArcs == 1)
            {
                // single swing or revolving.
                if (!filteredArcs[0].IsBound)
                {
                    return("REVOLVING");
                }

                KeyValuePair <double, double> endParams = GetAdjustedEndParameters(filteredArcs[0], flippedArcs[0], offsetAngles[0]);
                if ((endParams.Value - endParams.Key) <= Math.PI + angleEps)
                {
                    if ((Math.Abs(endParams.Key) <= angleEps) || (Math.Abs(endParams.Key - Math.PI) <= angleEps))
                    {
                        return("SINGLE_SWING_LEFT");
                    }
                    if ((Math.Abs(endParams.Value - Math.PI) <= angleEps) || (Math.Abs(endParams.Value - 2.0 * Math.PI) <= angleEps))
                    {
                        return("SINGLE_SWING_RIGHT");
                    }
                }
            }
            else if (numArcs == 2)
            {
                if (filteredArcs[0].IsBound && filteredArcs[1].IsBound)
                {
                    XYZ ctrDiff = filteredArcs[1].Center - filteredArcs[0].Center;

                    bool sameX = (Math.Abs(ctrDiff.X) < ShortDist);
                    bool sameY = (Math.Abs(ctrDiff.Y) < ShortDist);

                    if (sameX ^ sameY)
                    {
                        KeyValuePair <double, double> endParams1 = GetAdjustedEndParameters(filteredArcs[0], flippedArcs[0], offsetAngles[0]);
                        double angle1 = endParams1.Value - endParams1.Key;
                        if (angle1 <= Math.PI + 2.0 * smallAngle)
                        {
                            KeyValuePair <double, double> endParams2 = GetAdjustedEndParameters(filteredArcs[1], flippedArcs[1], offsetAngles[1]);
                            double angle2 = endParams2.Value - endParams2.Key;
                            if (angle2 <= Math.PI + 2.0 * smallAngle)
                            {
                                if (sameX)
                                {
                                    if (((Math.Abs(endParams1.Value - Math.PI) < smallAngle) && (Math.Abs(endParams2.Key - Math.PI) < smallAngle)) ||
                                        ((Math.Abs(endParams1.Key - Math.PI) < smallAngle) && (Math.Abs(endParams2.Value - Math.PI) < smallAngle)))
                                    {
                                        return("DOUBLE_SWING_RIGHT");
                                    }
                                    else if (((Math.Abs(endParams1.Value - 2.0 * Math.PI) < smallAngle) && (Math.Abs(endParams2.Key) < smallAngle)) ||
                                             ((Math.Abs(endParams1.Key) < smallAngle) && (Math.Abs(endParams2.Value - 2.0 * Math.PI) < smallAngle)))
                                    {
                                        return("DOUBLE_SWING_LEFT");
                                    }
                                }
                                else // if (sameY)
                                {
                                    return("DOUBLE_DOOR_SINGLE_SWING");
                                }
                            }
                        }
                    }
                }
            }
            else if (numArcs == 4)
            {
                IList <XYZ> ctrs = new List <XYZ>();
                IList <KeyValuePair <double, double> > endParams = new List <KeyValuePair <double, double> >();
                bool canContinue = true;

                // "sort" by quadrant.
                IList <int> whichQuadrant = new List <int>();
                for (int ii = 0; ii < 4; ii++)
                {
                    whichQuadrant.Add(-1);
                }

                for (int ii = 0; (ii < 4) && canContinue; ii++)
                {
                    ctrs.Add(filteredArcs[ii].Center);
                    if (filteredArcs[ii].IsBound)
                    {
                        endParams.Add(GetAdjustedEndParameters(filteredArcs[ii], flippedArcs[ii], offsetAngles[ii]));
                        double angle = endParams[ii].Value - endParams[ii].Key;
                        if (angle > Math.PI + 2.0 * smallAngle)
                        {
                            canContinue = false;
                        }
                        else if ((Math.Abs(endParams[ii].Key) < smallAngle) && whichQuadrant[0] == -1)
                        {
                            whichQuadrant[0] = ii;
                        }
                        else if ((Math.Abs(endParams[ii].Value - Math.PI) < smallAngle) && whichQuadrant[1] == -1)
                        {
                            whichQuadrant[1] = ii;
                        }
                        else if ((Math.Abs(endParams[ii].Key - Math.PI) < smallAngle) && whichQuadrant[2] == -1)
                        {
                            whichQuadrant[2] = ii;
                        }
                        else if ((Math.Abs(endParams[ii].Value - 2.0 * Math.PI) < smallAngle) && whichQuadrant[3] == -1)
                        {
                            whichQuadrant[3] = ii;
                        }
                        else
                        {
                            canContinue = false;
                        }
                    }
                    else
                    {
                        canContinue = false;
                    }
                }

                if (canContinue)
                {
                    XYZ ctrDiff1 = ctrs[whichQuadrant[3]] - ctrs[whichQuadrant[0]];
                    XYZ ctrDiff2 = ctrs[whichQuadrant[2]] - ctrs[whichQuadrant[1]];
                    XYZ ctrDiff3 = ctrs[whichQuadrant[1]] - ctrs[whichQuadrant[0]];

                    if ((Math.Abs(ctrDiff1[0]) < ShortDist) &&
                        (Math.Abs(ctrDiff2[0]) < ShortDist) &&
                        (Math.Abs(ctrDiff3[1]) < ShortDist))
                    {
                        return("DOUBLE_DOOR_DOUBLE_SWING");
                    }
                }
            }

            return("NOTDEFINED");
        }