bool GetArrowHead(On2dVector dir, On2dPoint tip, double scale, ref On3dPointArray triangle)
        {
            double arrow_size = m_default_arrow_size * scale;

            On2dPointArray corners = new On2dPointArray();

            corners.Reserve(3);
            corners.SetCount(3);

            On2dVector up = new On2dVector(-dir.y, dir.x);

            corners[0].Set(tip.x, tip.y);
            corners[1].x = tip.x + arrow_size * (0.25 * up.x - dir.x);
            corners[1].y = tip.y + arrow_size * (0.25 * up.y - dir.y);
            corners[2].x = corners[1].x - 0.5 * arrow_size * up.x;
            corners[2].y = corners[1].y - 0.5 * arrow_size * up.y;

            triangle.Reserve(corners.Count());
            triangle.SetCount(corners.Count());

            for (int i = 0; i < corners.Count(); i++)
            {
                triangle[i] = m_plane.PointAt(corners[i].x, corners[i].y);
            }

            return(true);
        }
        private static OnCurve CreateOuterTrimmingCurve(
            OnSurface s,
            int side                   // 0 = SW to SE
            // 1 = SE to NE
            // 2 = NE to NW
            // 3 = NW to SW
            )
        {
            // A trimming curve is a 2d curve whose image lies in the surface's domain.
            // The "active" portion of the surface is to the left of the trimming curve.
            // An outer trimming loop consists of a simple closed curve running
            // counter-clockwise around the region it trims.

            //In cases when trim curve is not easily defined in surface domain,
            //use ON_Surface::Pullback only be careful about curve direction to ensure
            //loop trims run anti-clockwise for outer loop and clockwise for inner loop.

            //In this case, trim curves lie on the four edges of the surface
            On2dPoint from = new On2dPoint();
            On2dPoint to = new On2dPoint();
            double    u0 = double.NaN, u1 = double.NaN, v0 = double.NaN, v1 = double.NaN;

            s.GetDomain(0, ref u0, ref u1);
            s.GetDomain(1, ref v0, ref v1);

            switch (side)
            {
            case 0: // SW to SE
                from.x = u0; from.y = v0;
                to.x   = u1; to.y = v0;
                break;

            case 1: // SE to NE
                from.x = u1; from.y = v0;
                to.x   = u1; to.y = v1;
                break;

            case 2: // NE to NW
                from.x = u1; from.y = v1;
                to.x   = u0; to.y = v1;
                break;

            case 3: // NW to SW
                from.x = u0; from.y = v1;
                to.x   = u0; to.y = v0;
                break;

            default:
                return(null);
            }

            OnCurve c2d = new OnLineCurve(from, to);

            if (c2d != null)
            {
                c2d.SetDomain(0.0, 1.0);
            }
            return(c2d);
        }
Esempio n. 3
0
        /// <summary>
        /// TwistedCubeTrimmingCurve
        /// </summary>
        static OnCurve TwistedCubeTrimmingCurve(
            IOnSurface s,
            int side // 0 = SW to SE
                     // 1 = SE to NE
                     // 2 = NE to NW
                     // 3 = NW to SW
            )
        {
            // A trimming curve is a 2d curve whose image lies in the surface's domain.
            // The "active" portion of the surface is to the left of the trimming curve.
            // An outer trimming loop consists of a simple closed curve running
            // counter-clockwise around the region it trims.

            On2dPoint from = new On2dPoint();
            On2dPoint to = new On2dPoint();
            double    u0 = 0.0, u1 = 0.0, v0 = 0.0, v1 = 0.0;

            s.GetDomain(0, ref u0, ref u1);
            s.GetDomain(1, ref v0, ref v1);

            switch (side)
            {
            case 0: // SW to SE
                from.x = u0; from.y = v0;
                to.x   = u1; to.y = v0;
                break;

            case 1: // SE to NE
                from.x = u1; from.y = v0;
                to.x   = u1; to.y = v1;
                break;

            case 2: // NE to NW
                from.x = u1; from.y = v1;
                to.x   = u0; to.y = v1;
                break;

            case 3: // NW to SW
                from.x = u0; from.y = v1;
                to.x   = u0; to.y = v0;
                break;

            default:
                return(null);
            }

            OnLineCurve c2d = new OnLineCurve(from, to);

            c2d.SetDomain(0.0, 1.0);

            return(c2d);
        }
        private static OnCurve CreateTrimmingCurve(
            OnSurface s,
            int side                    // 0 = SW to SE
            // 1 = SE to NE
            // 2 = NE to NW
            // 3 = NW to SW
            )
        {
            // A trimming curve is a 2d curve whose image lies in the surface's domain.
            // The "active" portion of the surface is to the left of the trimming curve.
            // An outer trimming loop consists of a simple closed curve running
            // counter-clockwise around the region it trims.
            // An inner trimming loop consists of a simple closed curve running
            // clockwise around the region the hole.

            On2dPoint from = new On2dPoint();
            On2dPoint to = new On2dPoint();
            double    u0 = double.NaN, u1 = double.NaN, v0 = double.NaN, v1 = double.NaN;

            s.GetDomain(0, ref u0, ref u1);
            s.GetDomain(1, ref v0, ref v1);

            switch (side)
            {
            case 0: // SW to SE
                from.x = u0; from.y = v0;
                to.x   = u1; to.y = v0;
                break;

            case 1: // diagonal
                from.x = u1; from.y = v0;
                to.x   = (u0 + u1) / 2; to.y = v1;
                break;

            case 2: // diagonal
                from.x = (u0 + u1) / 2; from.y = v1;
                to.x   = u0; to.y = v0;
                break;

            default:
                return(null);
            }

            OnCurve c2d = new OnLineCurve(from, to);

            if (c2d != null)
            {
                c2d.SetDomain(0.0, 1.0);
            }
            return(c2d);
        }
        /// <summary>
        /// Public constructor
        /// </summary>
        public SampleCsDrawArrowheadConduit(OnPlane plane, OnLine line, double scale)
            : base(new MSupportChannels(MSupportChannels.SC_CALCBOUNDINGBOX | MSupportChannels.SC_DRAWOVERLAY), false)
        {
            m_bDraw     = false;
            m_plane     = plane;
            m_line      = line;
            m_arrowhead = new On3dPointArray();

            double x = 0, y = 0;

            m_plane.ClosestPointTo(line.from, ref x, ref y);
            On2dPoint from = new On2dPoint(x, y);

            m_plane.ClosestPointTo(line.to, ref x, ref y);
            On2dPoint to = new On2dPoint(x, y);

            On2dVector dir = new On2dVector(from - to);

            dir.Unitize();

            m_bDraw = GetArrowHead(dir, from, scale, ref m_arrowhead);
        }
        bool GetArrowHead(On2dVector dir, On2dPoint tip, double scale, ref On3dPointArray triangle)
        {
            double arrow_size = m_default_arrow_size * scale;

              On2dPointArray corners = new On2dPointArray();
              corners.Reserve(3);
              corners.SetCount(3);

              On2dVector up = new On2dVector(-dir.y, dir.x);
              corners[0].Set(tip.x, tip.y);
              corners[1].x = tip.x + arrow_size * (0.25 * up.x - dir.x);
              corners[1].y = tip.y + arrow_size * (0.25 * up.y - dir.y);
              corners[2].x = corners[1].x - 0.5 * arrow_size * up.x;
              corners[2].y = corners[1].y - 0.5 * arrow_size * up.y;

              triangle.Reserve(corners.Count());
              triangle.SetCount(corners.Count());

              for (int i = 0; i < corners.Count(); i++)
            triangle[i] = m_plane.PointAt(corners[i].x, corners[i].y);

              return true;
        }
        /// <summary>
        /// Public constructor
        /// </summary>
        public SampleCsDrawArrowheadConduit(OnPlane plane, OnLine line, double scale)
            : base(new MSupportChannels(MSupportChannels.SC_CALCBOUNDINGBOX | MSupportChannels.SC_DRAWOVERLAY), false)
        {
            m_bDraw = false;
              m_plane = plane;
              m_line = line;
              m_arrowhead = new On3dPointArray();

              double x = 0, y = 0;

              m_plane.ClosestPointTo(line.from, ref x, ref y);
              On2dPoint from = new On2dPoint(x, y);

              m_plane.ClosestPointTo(line.to, ref x, ref y);
              On2dPoint to = new On2dPoint(x, y);

              On2dVector dir = new On2dVector(from - to);
              dir.Unitize();

              m_bDraw = GetArrowHead(dir, from, scale, ref m_arrowhead);
        }
        /// <summary>
        /// TwistedCubeTrimmingCurve
        /// </summary>
        static OnCurve TwistedCubeTrimmingCurve(
      IOnSurface s,
      int side // 0 = SW to SE
               // 1 = SE to NE
               // 2 = NE to NW
               // 3 = NW to SW
      )
        {
            // A trimming curve is a 2d curve whose image lies in the surface's domain.
              // The "active" portion of the surface is to the left of the trimming curve.
              // An outer trimming loop consists of a simple closed curve running
              // counter-clockwise around the region it trims.

              On2dPoint from = new On2dPoint();
              On2dPoint to = new On2dPoint();
              double u0 = 0.0, u1 = 0.0, v0 = 0.0, v1 = 0.0;

              s.GetDomain(0, ref u0, ref u1);
              s.GetDomain(1, ref v0, ref v1);

              switch (side)
              {
              case 0:  // SW to SE
            from.x = u0; from.y = v0;
            to.x   = u1; to.y   = v0;
            break;
              case 1: // SE to NE
            from.x = u1; from.y = v0;
            to.x   = u1; to.y   = v1;
            break;
              case 2: // NE to NW
            from.x = u1; from.y = v1;
            to.x   = u0; to.y   = v1;
            break;
              case 3: // NW to SW
            from.x = u0; from.y = v1;
            to.x   = u0; to.y   = v0;
            break;
              default:
            return null;
              }

              OnLineCurve c2d = new OnLineCurve(from, to);
              c2d.SetDomain(0.0, 1.0);

              return c2d;
        }
        private static OnCurve CreateOuterTrimmingCurve(
                              OnSurface s,
                              int side // 0 = SW to SE
      // 1 = SE to NE
      // 2 = NE to NW
      // 3 = NW to SW
                              )
        {
            // A trimming curve is a 2d curve whose image lies in the surface's domain.
              // The "active" portion of the surface is to the left of the trimming curve.
              // An outer trimming loop consists of a simple closed curve running
              // counter-clockwise around the region it trims.

              //In cases when trim curve is not easily defined in surface domain,
              //use ON_Surface::Pullback only be careful about curve direction to ensure
              //loop trims run anti-clockwise for outer loop and clockwise for inner loop.

              //In this case, trim curves lie on the four edges of the surface
              On2dPoint from = new On2dPoint();
              On2dPoint to = new On2dPoint();
              double u0 = double.NaN, u1 = double.NaN, v0 = double.NaN, v1 = double.NaN;

              s.GetDomain(0, ref u0, ref u1);
              s.GetDomain(1, ref v0, ref v1);

              switch (side)
              {
            case 0:  // SW to SE
              from.x = u0; from.y = v0;
              to.x = u1; to.y = v0;
              break;
            case 1: // SE to NE
              from.x = u1; from.y = v0;
              to.x = u1; to.y = v1;
              break;
            case 2: // NE to NW
              from.x = u1; from.y = v1;
              to.x = u0; to.y = v1;
              break;
            case 3: // NW to SW
              from.x = u0; from.y = v1;
              to.x = u0; to.y = v0;
              break;
            default:
              return null;
              }

              OnCurve c2d = new OnLineCurve(from, to);
              if (c2d != null)
            c2d.SetDomain(0.0, 1.0);
              return c2d;
        }
        //Trim curves must run is clockwise direction
        private static OnCurve CreateInnerTrimmingCurve(
                  OnSurface s,
                  int side // 0 = near SE to SW
      // 1 = near SW to NW
      // 2 = near NW to NE
      // 3 = near NE to SE
                  )
        {
            // A trimming curve is a 2d curve whose image lies in the surface's domain.
              // The "active" portion of the surface is to the left of the trimming curve.
              // An inner trimming loop consists of a simple closed curve running
              // clockwise around the region the hole.

              //In this case, trim curves lie with 0.2 domain distance from surface edge
              On2dPoint from = new On2dPoint();
              On2dPoint to = new On2dPoint();
              double u0 = double.NaN,
              u1 = double.NaN,
              v0 = double.NaN,
              v1 = double.NaN;

              s.GetDomain(0, ref u0, ref u1);
              s.GetDomain(1, ref v0, ref v1);

              double udis = 0.2 * (u1 - u0);
              double vdis = 0.2 * (v1 - v0);

              u0 += udis;
              u1 -= udis;
              v0 += vdis;
              v1 -= vdis;

              switch (side)
              {
            case 0:  // near SE to SW
              from.x = u1; from.y = v0;
              to.x = u0; to.y = v0;
              break;
            case 1: // near SW to NW
              from.x = u0; from.y = v0;
              to.x = u0; to.y = v1;
              break;
            case 2: // near NW to NE
              from.x = u0; from.y = v1;
              to.x = u1; to.y = v1;
              break;
            case 3: // near NE to SE
              from.x = u1; from.y = v1;
              to.x = u1; to.y = v0;
              break;
            default:
              return null;
              }

              OnCurve c2d = new OnLineCurve(from, to);
              if (c2d != null)
            c2d.SetDomain(0.0, 1.0);

              return c2d;
        }
        /// <summary>
        /// The one and only MakeBox
        /// </summary>
        static OnBrep MakeBox()
        {
            /*
              This example demonstrates how to construct a OnBrep
              with the topology shown below.

              v7_______e6_____v6
               |\             |\
               | e7           | e5
               |  \ ______e4_____\
              e11  v4         |   v5
               |   |        e10   |
               |   |          |   |
              v3---|---e2----v2   e9
               \   e8         \   |
            e3 |           e1 |
             \ |            \ |
              \v0_____e0_____\v1

              */

              On3dPoint[] points = new On3dPoint[8];
              points[0] = new On3dPoint(0.0, 0.0, 0.0);
              points[1] = new On3dPoint(10.0, 0.0, 0.0);
              points[2] = new On3dPoint(10.0, 10.0, 0.0);
              points[3] = new On3dPoint(0.0, 10.0, 0.0);
              points[4] = new On3dPoint(0.0, 0.0, 10.0);
              points[5] = new On3dPoint(10.0, 0.0, 10.0);
              points[6] = new On3dPoint(10.0, 10.0, 10.0);
              points[7] = new On3dPoint(0.0, 10.0, 10.0);

              OnBrep brep = new OnBrep();

              int vi = 0, ei = 0, fi = 0, si = 0, c2i = 0;

              for (vi = 0; vi < 8; vi++)
            brep.NewVertex(points[vi], 0.0);

              for (ei = 0; ei < 4; ei++)
              {
            OnBrepVertex v0 = brep.m_V[ei];
            OnBrepVertex v1 = brep.m_V[(ei + 1) % 4];
            brep.m_C3.Append(new OnLineCurve(v0.point, v1.point));
            brep.NewEdge(ref v0, ref v1, ei, null, 0.0);
              }
              for (ei = 4; ei < 8; ei++)
              {
            OnBrepVertex v0 = brep.m_V[ei];
            OnBrepVertex v1 = brep.m_V[ei == 7 ? 4 : (ei + 1)];
            brep.m_C3.Append(new OnLineCurve(v0.point, v1.point));
            brep.NewEdge(ref v0, ref v1, ei, null, 0.0);
              }
              for (ei = 8; ei < 12; ei++)
              {
            OnBrepVertex v0 = brep.m_V[ei - 8];
            OnBrepVertex v1 = brep.m_V[ei - 4];
            brep.m_C3.Append(new OnLineCurve(v0.point, v1.point));
            brep.NewEdge(ref v0, ref v1, ei, null, 0.0);
              }

              OnBrepBoxFaceInfo[] f = new OnBrepBoxFaceInfo[6];
              f[0] = new OnBrepBoxFaceInfo(0, 9, 4, 8, false, false, true, true);
              f[1] = new OnBrepBoxFaceInfo(1, 10, 5, 9, false, false, true, true);
              f[2] = new OnBrepBoxFaceInfo(2, 11, 6, 10, false, false, true, true);
              f[3] = new OnBrepBoxFaceInfo(3, 8, 7, 11, false, false, true, true);
              f[4] = new OnBrepBoxFaceInfo(3, 2, 1, 0, true, true, true, true);
              f[5] = new OnBrepBoxFaceInfo(4, 5, 6, 7, false, false, false, false);

              for (fi = 0; fi < 6; fi++ )
              {
            OnBrepEdge e0 = brep.m_E[f[fi].e[0]];
            OnBrepEdge e1 = brep.m_E[f[fi].e[1]];
            OnBrepEdge e2 = brep.m_E[f[fi].e[2]];
            OnBrepEdge e3 = brep.m_E[f[fi].e[3]];
            OnBrepVertex v0 = brep.m_V[e0.get_m_vi(f[fi].bRev[0] ? 1 : 0)];
            OnBrepVertex v1 = brep.m_V[e1.get_m_vi(f[fi].bRev[1] ? 1 : 0)];
            OnBrepVertex v2 = brep.m_V[e2.get_m_vi(f[fi].bRev[2] ? 1 : 0)];
            OnBrepVertex v3 = brep.m_V[e3.get_m_vi(f[fi].bRev[3] ? 1 : 0)];

            si = brep.AddSurface(OnUtil.ON_NurbsSurfaceQuadrilateral(v0.point, v1.point, v2.point, v3.point));
            OnInterval s = brep.m_S[si].Domain(0);
            OnInterval t = brep.m_S[si].Domain(1);
            On2dPoint p0 = new On2dPoint(s[0], t[0]);
            On2dPoint p1 = new On2dPoint(s[1], t[0]);
            On2dPoint p2 = new On2dPoint(s[1], t[1]);
            On2dPoint p3 = new On2dPoint(s[0], t[1]);

            OnBrepFace face = brep.NewFace(si);
            OnBrepLoop loop = brep.NewLoop(IOnBrepLoop.TYPE.outer, ref face);

            loop.m_pbox.m_min.x = s[0];
            loop.m_pbox.m_min.y = t[0];
            loop.m_pbox.m_min.z = 0.0;

            loop.m_pbox.m_max.x = s[1];
            loop.m_pbox.m_max.y = t[1];
            loop.m_pbox.m_max.z = 0.0;

            // south side of surface
            c2i = brep.AddTrimCurve(new OnLineCurve(p0, p1));
            OnBrepTrim trim0 = brep.NewTrim(ref e0, f[fi].bRev[0], ref loop, c2i);
            trim0.set_m_tolerance(0, 0.0);
            trim0.set_m_tolerance(1, 0.0);
            trim0.m_type = (trim0.get_m_vi(0) != trim0.get_m_vi(1)) ? IOnBrepTrim.TYPE.mated : IOnBrepTrim.TYPE.singular;
            trim0.m_iso = IOnSurface.ISO.S_iso;

            // east side of surface
            c2i = brep.AddTrimCurve(new OnLineCurve(p1, p2));
            OnBrepTrim trim1 = brep.NewTrim(ref e1, f[fi].bRev[1], ref loop, c2i);
            trim1.set_m_tolerance(0, 0.0);
            trim1.set_m_tolerance(1, 0.0);
            trim1.m_type = (trim1.get_m_vi(0) != trim1.get_m_vi(1)) ? IOnBrepTrim.TYPE.mated : IOnBrepTrim.TYPE.singular;
            trim1.m_iso = IOnSurface.ISO.E_iso;

            // north side of surface
            c2i = brep.AddTrimCurve(new OnLineCurve(p2, p3));
            OnBrepTrim trim2 = brep.NewTrim(ref e2, f[fi].bRev[2], ref loop, c2i);
            trim2.set_m_tolerance(0, 0.0);
            trim2.set_m_tolerance(1, 0.0);
            trim2.m_type = (trim2.get_m_vi(0) != trim2.get_m_vi(1)) ? IOnBrepTrim.TYPE.mated : IOnBrepTrim.TYPE.singular;
            trim2.m_iso = IOnSurface.ISO.N_iso;

            // west side of surface
            c2i = brep.AddTrimCurve(new OnLineCurve(p3, p0));
            OnBrepTrim trim3 = brep.NewTrim(ref e3, f[fi].bRev[3], ref loop, c2i);
            trim3.set_m_tolerance(0, 0.0);
            trim3.set_m_tolerance(1, 0.0);
            trim3.m_type = (trim3.get_m_vi(0) != trim3.get_m_vi(1)) ? IOnBrepTrim.TYPE.mated : IOnBrepTrim.TYPE.singular;
            trim3.m_iso = IOnSurface.ISO.W_iso;
              }

              if (!brep.IsValid())
            return null;

              return brep;
        }
        /// <summary>
        /// The one and only MakeBox
        /// </summary>
        static OnBrep MakeBox()
        {
            /*
             * This example demonstrates how to construct a OnBrep
             * with the topology shown below.
             *
             * v7_______e6_____v6
             |\             |\
             | e7           | e5
             |  \ ______e4_____\
             | e11  v4         |   v5
             |   |        e10   |
             |   |          |   |
             | v3---|---e2----v2   e9
             \   e8         \   |
             \ e3 |           e1 |
             \ |            \ |
             \  \v0_____e0_____\v1
             \
             */

            On3dPoint[] points = new On3dPoint[8];
            points[0] = new On3dPoint(0.0, 0.0, 0.0);
            points[1] = new On3dPoint(10.0, 0.0, 0.0);
            points[2] = new On3dPoint(10.0, 10.0, 0.0);
            points[3] = new On3dPoint(0.0, 10.0, 0.0);
            points[4] = new On3dPoint(0.0, 0.0, 10.0);
            points[5] = new On3dPoint(10.0, 0.0, 10.0);
            points[6] = new On3dPoint(10.0, 10.0, 10.0);
            points[7] = new On3dPoint(0.0, 10.0, 10.0);

            OnBrep brep = new OnBrep();

            int vi = 0, ei = 0, fi = 0, si = 0, c2i = 0;

            for (vi = 0; vi < 8; vi++)
            {
                brep.NewVertex(points[vi], 0.0);
            }

            for (ei = 0; ei < 4; ei++)
            {
                OnBrepVertex v0 = brep.m_V[ei];
                OnBrepVertex v1 = brep.m_V[(ei + 1) % 4];
                brep.m_C3.Append(new OnLineCurve(v0.point, v1.point));
                brep.NewEdge(ref v0, ref v1, ei, null, 0.0);
            }
            for (ei = 4; ei < 8; ei++)
            {
                OnBrepVertex v0 = brep.m_V[ei];
                OnBrepVertex v1 = brep.m_V[ei == 7 ? 4 : (ei + 1)];
                brep.m_C3.Append(new OnLineCurve(v0.point, v1.point));
                brep.NewEdge(ref v0, ref v1, ei, null, 0.0);
            }
            for (ei = 8; ei < 12; ei++)
            {
                OnBrepVertex v0 = brep.m_V[ei - 8];
                OnBrepVertex v1 = brep.m_V[ei - 4];
                brep.m_C3.Append(new OnLineCurve(v0.point, v1.point));
                brep.NewEdge(ref v0, ref v1, ei, null, 0.0);
            }

            OnBrepBoxFaceInfo[] f = new OnBrepBoxFaceInfo[6];
            f[0] = new OnBrepBoxFaceInfo(0, 9, 4, 8, false, false, true, true);
            f[1] = new OnBrepBoxFaceInfo(1, 10, 5, 9, false, false, true, true);
            f[2] = new OnBrepBoxFaceInfo(2, 11, 6, 10, false, false, true, true);
            f[3] = new OnBrepBoxFaceInfo(3, 8, 7, 11, false, false, true, true);
            f[4] = new OnBrepBoxFaceInfo(3, 2, 1, 0, true, true, true, true);
            f[5] = new OnBrepBoxFaceInfo(4, 5, 6, 7, false, false, false, false);

            for (fi = 0; fi < 6; fi++)
            {
                OnBrepEdge   e0 = brep.m_E[f[fi].e[0]];
                OnBrepEdge   e1 = brep.m_E[f[fi].e[1]];
                OnBrepEdge   e2 = brep.m_E[f[fi].e[2]];
                OnBrepEdge   e3 = brep.m_E[f[fi].e[3]];
                OnBrepVertex v0 = brep.m_V[e0.get_m_vi(f[fi].bRev[0] ? 1 : 0)];
                OnBrepVertex v1 = brep.m_V[e1.get_m_vi(f[fi].bRev[1] ? 1 : 0)];
                OnBrepVertex v2 = brep.m_V[e2.get_m_vi(f[fi].bRev[2] ? 1 : 0)];
                OnBrepVertex v3 = brep.m_V[e3.get_m_vi(f[fi].bRev[3] ? 1 : 0)];

                si = brep.AddSurface(OnUtil.ON_NurbsSurfaceQuadrilateral(v0.point, v1.point, v2.point, v3.point));
                OnInterval s  = brep.m_S[si].Domain(0);
                OnInterval t  = brep.m_S[si].Domain(1);
                On2dPoint  p0 = new On2dPoint(s[0], t[0]);
                On2dPoint  p1 = new On2dPoint(s[1], t[0]);
                On2dPoint  p2 = new On2dPoint(s[1], t[1]);
                On2dPoint  p3 = new On2dPoint(s[0], t[1]);

                OnBrepFace face = brep.NewFace(si);
                OnBrepLoop loop = brep.NewLoop(IOnBrepLoop.TYPE.outer, ref face);

                loop.m_pbox.m_min.x = s[0];
                loop.m_pbox.m_min.y = t[0];
                loop.m_pbox.m_min.z = 0.0;

                loop.m_pbox.m_max.x = s[1];
                loop.m_pbox.m_max.y = t[1];
                loop.m_pbox.m_max.z = 0.0;

                // south side of surface
                c2i = brep.AddTrimCurve(new OnLineCurve(p0, p1));
                OnBrepTrim trim0 = brep.NewTrim(ref e0, f[fi].bRev[0], ref loop, c2i);
                trim0.set_m_tolerance(0, 0.0);
                trim0.set_m_tolerance(1, 0.0);
                trim0.m_type = (trim0.get_m_vi(0) != trim0.get_m_vi(1)) ? IOnBrepTrim.TYPE.mated : IOnBrepTrim.TYPE.singular;
                trim0.m_iso  = IOnSurface.ISO.S_iso;

                // east side of surface
                c2i = brep.AddTrimCurve(new OnLineCurve(p1, p2));
                OnBrepTrim trim1 = brep.NewTrim(ref e1, f[fi].bRev[1], ref loop, c2i);
                trim1.set_m_tolerance(0, 0.0);
                trim1.set_m_tolerance(1, 0.0);
                trim1.m_type = (trim1.get_m_vi(0) != trim1.get_m_vi(1)) ? IOnBrepTrim.TYPE.mated : IOnBrepTrim.TYPE.singular;
                trim1.m_iso  = IOnSurface.ISO.E_iso;

                // north side of surface
                c2i = brep.AddTrimCurve(new OnLineCurve(p2, p3));
                OnBrepTrim trim2 = brep.NewTrim(ref e2, f[fi].bRev[2], ref loop, c2i);
                trim2.set_m_tolerance(0, 0.0);
                trim2.set_m_tolerance(1, 0.0);
                trim2.m_type = (trim2.get_m_vi(0) != trim2.get_m_vi(1)) ? IOnBrepTrim.TYPE.mated : IOnBrepTrim.TYPE.singular;
                trim2.m_iso  = IOnSurface.ISO.N_iso;

                // west side of surface
                c2i = brep.AddTrimCurve(new OnLineCurve(p3, p0));
                OnBrepTrim trim3 = brep.NewTrim(ref e3, f[fi].bRev[3], ref loop, c2i);
                trim3.set_m_tolerance(0, 0.0);
                trim3.set_m_tolerance(1, 0.0);
                trim3.m_type = (trim3.get_m_vi(0) != trim3.get_m_vi(1)) ? IOnBrepTrim.TYPE.mated : IOnBrepTrim.TYPE.singular;
                trim3.m_iso  = IOnSurface.ISO.W_iso;
            }

            if (!brep.IsValid())
            {
                return(null);
            }

            return(brep);
        }
        //Trim curves must run is clockwise direction
        private static OnCurve CreateInnerTrimmingCurve(
            OnSurface s,
            int side       // 0 = near SE to SW
            // 1 = near SW to NW
            // 2 = near NW to NE
            // 3 = near NE to SE
            )
        {
            // A trimming curve is a 2d curve whose image lies in the surface's domain.
            // The "active" portion of the surface is to the left of the trimming curve.
            // An inner trimming loop consists of a simple closed curve running
            // clockwise around the region the hole.

            //In this case, trim curves lie with 0.2 domain distance from surface edge
            On2dPoint from = new On2dPoint();
            On2dPoint to   = new On2dPoint();
            double    u0   = double.NaN,
                      u1   = double.NaN,
                      v0   = double.NaN,
                      v1   = double.NaN;

            s.GetDomain(0, ref u0, ref u1);
            s.GetDomain(1, ref v0, ref v1);

            double udis = 0.2 * (u1 - u0);
            double vdis = 0.2 * (v1 - v0);

            u0 += udis;
            u1 -= udis;
            v0 += vdis;
            v1 -= vdis;

            switch (side)
            {
            case 0: // near SE to SW
                from.x = u1; from.y = v0;
                to.x   = u0; to.y = v0;
                break;

            case 1: // near SW to NW
                from.x = u0; from.y = v0;
                to.x   = u0; to.y = v1;
                break;

            case 2: // near NW to NE
                from.x = u0; from.y = v1;
                to.x   = u1; to.y = v1;
                break;

            case 3: // near NE to SE
                from.x = u1; from.y = v1;
                to.x   = u1; to.y = v0;
                break;

            default:
                return(null);
            }

            OnCurve c2d = new OnLineCurve(from, to);

            if (c2d != null)
            {
                c2d.SetDomain(0.0, 1.0);
            }

            return(c2d);
        }