/// <summary>
        /// MakeTwistedCubeTrimmingLoop
        /// </summary>
        static int MakeTwistedCubeTrimmingLoop(
      ref OnBrep brep, // returns index of loop
      ref OnBrepFace face,  // face loop is on
      int vSWi, int vSEi, int vNEi, int vNWi, // Indices of corner vertices listed in SW, SE, NW, NE order
      int eSi,     // index of edge on south side of surface
      int eS_dir,  // orientation of edge with respect to surface trim
      int eEi,     // index of edge on south side of surface
      int eE_dir,  // orientation of edge with respect to surface trim
      int eNi,     // index of edge on south side of surface
      int eN_dir,  // orientation of edge with respect to surface trim
      int eWi,     // index of edge on south side of surface
      int eW_dir   // orientation of edge with respect to surface trim
                                   )
        {
            IOnSurface srf = brep.m_S[face.m_si];

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

              // Create trimming curves running counter clockwise around the surface's domain.
              // Start at the south side
              int c2i = 0, ei = 0;
              bool bRev3d = false;
              IOnSurface.ISO iso = IOnSurface.ISO.not_iso;

              for (int side = 0; side < 4; side++ )
              {
            // side: 0=south, 1=east, 2=north, 3=west
            OnCurve c2 = TwistedCubeTrimmingCurve(srf, side);
            c2i = brep.m_C2.Count();
            brep.m_C2.Append(c2);

            switch (side)
            {
            case 0: // south
              ei = eSi;
              bRev3d = (eS_dir == -1);
              iso = IOnSurface.ISO.S_iso;
              break;
            case 1: // east
              ei = eEi;
              bRev3d = (eE_dir == -1);
              iso = IOnSurface.ISO.E_iso;
              break;
            case 2: // north
              ei = eNi;
              bRev3d = (eN_dir == -1);
              iso = IOnSurface.ISO.N_iso;
              break;
            case 3: // west
              ei = eWi;
              bRev3d = (eW_dir == -1);
              iso = IOnSurface.ISO.W_iso;
              break;
            }

            OnBrepEdge edge = brep.m_E[ei];
            OnBrepTrim trim = brep.NewTrim(ref edge, bRev3d, ref loop, c2i);
            trim.m_iso = iso;
            trim.m_type = IOnBrepTrim.TYPE.mated; // This b-rep is closed, so all trims have mates.
            trim.set_m_tolerance(0, 0.0); // This simple example is exact - for models with
            trim.set_m_tolerance(1, 0.0); // non-exact data, set tolerance as explained in
                                      // definition of OnBrepTrim.
              }

              return loop.m_loop_index;
        }
        private static int MakeTrimmingLoop(ref OnBrep brep, // returns index of loop
         ref OnBrepFace face,  // face loop is on
         int v0, int v1, int v2, // Indices of corner vertices listed in A,B,C order
         int e0,     // index of first edge
         int e0_dir, // orientation of edge
         int e1,     // index second edgee
         int e1_dir, // orientation of edge
         int e2,     // index third edge
         int e2_dir  // orientation of edge
                                    )
        {
            OnSurface srf = brep.m_S[face.m_si];

              //Create new loop
              OnBrepLoop loop = brep.NewLoop(IOnBrepLoop.TYPE.outer, ref face);

              // Create trimming curves running counter clockwise around the surface's domain.
              // Note that trims of outer loops run counter clockwise while trims of inner loops (holes) run anti-clockwise.
              // Also note that when trims locate on surface N,S,E or W ends, then trim_iso becomes N_iso, S_iso, E_iso and W_iso respectfully.
              // While if trim is parallel to surface N,S or E,W, then trim is becomes y_iso and x_iso respectfully.

              // Start at the south side
              OnCurve c2;
              int c2i, ei = 0;
              bool bRev3d = false;
              IOnSurface.ISO iso = IOnSurface.ISO.not_iso;

              for (int side = 0; side < 3; side++)
              {
            // side: 0=south, 1=east, 2=north, 3=west

            c2 = CreateTrimmingCurve(srf, side);

            //Add trimming curve to brep trmming curves array
            c2i = brep.m_C2.Count();
            brep.m_C2.Append(c2);

            switch (side)
            {
              case 0: // south
            ei = e0;
            bRev3d = (e0_dir == -1);
            iso = IOnSurface.ISO.S_iso;
            break;
              case 1: // diagonal
            ei = e1;
            bRev3d = (e1_dir == -1);
            iso = IOnSurface.ISO.not_iso;
            break;
              case 2: // diagonal
            ei = e2;
            bRev3d = (e2_dir == -1);
            iso = IOnSurface.ISO.not_iso;
            break;
            }

            //Create new trim topology that references edge, direction reletive to edge, loop and trim curve geometry
            OnBrepEdge edge = brep.m_E[ei];
            OnBrepTrim trim = brep.NewTrim(ref edge, bRev3d, ref loop, c2i);
            if (trim != null)
            {
              trim.m_iso = iso;
              trim.m_type = IOnBrepTrim.TYPE.boundary; // This one b-rep face, so all trims are boundary ones.
              trim.set_m_tolerance(0, 0.0); // This simple example is exact - for models with non-exact
              trim.set_m_tolerance(1, 0.0); // data, set tolerance as explained in definition of ON_BrepTrim.
            }
              }
              return loop.m_loop_index;
        }
Beispiel #3
0
        /// <summary>
        /// MakeTwistedCubeTrimmingLoop
        /// </summary>
        static int MakeTwistedCubeTrimmingLoop(
            ref OnBrep brep,                        // returns index of loop
            ref OnBrepFace face,                    // face loop is on
            int vSWi, int vSEi, int vNEi, int vNWi, // Indices of corner vertices listed in SW, SE, NW, NE order
            int eSi,                                // index of edge on south side of surface
            int eS_dir,                             // orientation of edge with respect to surface trim
            int eEi,                                // index of edge on south side of surface
            int eE_dir,                             // orientation of edge with respect to surface trim
            int eNi,                                // index of edge on south side of surface
            int eN_dir,                             // orientation of edge with respect to surface trim
            int eWi,                                // index of edge on south side of surface
            int eW_dir                              // orientation of edge with respect to surface trim
            )
        {
            IOnSurface srf = brep.m_S[face.m_si];

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

            // Create trimming curves running counter clockwise around the surface's domain.
            // Start at the south side
            int  c2i = 0, ei = 0;
            bool bRev3d = false;

            IOnSurface.ISO iso = IOnSurface.ISO.not_iso;

            for (int side = 0; side < 4; side++)
            {
                // side: 0=south, 1=east, 2=north, 3=west
                OnCurve c2 = TwistedCubeTrimmingCurve(srf, side);
                c2i = brep.m_C2.Count();
                brep.m_C2.Append(c2);

                switch (side)
                {
                case 0: // south
                    ei     = eSi;
                    bRev3d = (eS_dir == -1);
                    iso    = IOnSurface.ISO.S_iso;
                    break;

                case 1: // east
                    ei     = eEi;
                    bRev3d = (eE_dir == -1);
                    iso    = IOnSurface.ISO.E_iso;
                    break;

                case 2: // north
                    ei     = eNi;
                    bRev3d = (eN_dir == -1);
                    iso    = IOnSurface.ISO.N_iso;
                    break;

                case 3: // west
                    ei     = eWi;
                    bRev3d = (eW_dir == -1);
                    iso    = IOnSurface.ISO.W_iso;
                    break;
                }

                OnBrepEdge edge = brep.m_E[ei];
                OnBrepTrim trim = brep.NewTrim(ref edge, bRev3d, ref loop, c2i);
                trim.m_iso  = iso;
                trim.m_type = IOnBrepTrim.TYPE.mated; // This b-rep is closed, so all trims have mates.
                trim.set_m_tolerance(0, 0.0);         // This simple example is exact - for models with
                trim.set_m_tolerance(1, 0.0);         // non-exact data, set tolerance as explained in
                                                      // definition of OnBrepTrim.
            }

            return(loop.m_loop_index);
        }
        private static int MakeInnerTrimmingLoop(ref OnBrep brep, // returns index of loop
         ref OnBrepFace face,  // face loop is on
         int vSWi, int vSEi, int vNEi, int vNWi, // Indices of hole vertices
         int eSi,     // index of edge close to south side of surface
         int eS_dir,  // orientation of edge with respect to surface trim
         int eEi,     // index of edge close to east side of surface
         int eE_dir,  // orientation of edge with respect to surface trim
         int eNi,     // index of edge close to north side of surface
         int eN_dir,  // orientation of edge with respect to surface trim
         int eWi,     // index of edge close to west side of surface
         int eW_dir   // orientation of edge with respect to surface trim
                            )
        {
            OnSurface srf = brep.m_S[face.m_si];
              //Create new inner loop
              OnBrepLoop loop = brep.NewLoop(IOnBrepLoop.TYPE.inner, ref face);

              // Create trimming curves running counter clockwise around the surface's domain.
              // Note that trims of outer loops run counter clockwise while trims of inner loops (holes) run clockwise.
              // Also note that when trims locate on surface N,S,E or W ends, then trim_iso becomes N_iso, S_iso, E_iso and W_iso respectfully.
              // While if trim is parallel to surface N,S or E,W, then trim iso becomes y_iso and x_iso respectfully.
              // All other cases, iso is set to not_iso

              // Start near the south side
              OnCurve c2;
              int c2i, ei = 0;
              bool bRev3d = false;
              IOnSurface.ISO iso = IOnSurface.ISO.not_iso;

              for (int side = 0; side < 4; side++)
              {
            // side: 0=near south(y_iso), 1=near west(x_iso), 2=near north(y_iso), 3=near east(x_iso)

            //Create trim 2d curve
            c2 = CreateInnerTrimmingCurve(srf, side);

            //Add trimming curve to brep trmming curves array
            c2i = brep.m_C2.Count();
            brep.m_C2.Append(c2);

            switch (side)
            {
              case 0: // near south
            ei = eSi;
            bRev3d = (eS_dir == -1);
            iso = IOnSurface.ISO.y_iso;
            break;
              case 1: // near west
            ei = eEi;
            bRev3d = (eE_dir == -1);
            iso = IOnSurface.ISO.x_iso;
            break;
              case 2: // near north
            ei = eNi;
            bRev3d = (eN_dir == -1);
            iso = IOnSurface.ISO.y_iso;
            break;
              case 3: // near east
            ei = eWi;
            bRev3d = (eW_dir == -1);
            iso = IOnSurface.ISO.x_iso;
            break;
            }

            //Create new trim topology that references edge, direction reletive to edge, loop and trim curve geometry
            OnBrepEdge edge = brep.m_E[ei];
            OnBrepTrim trim = brep.NewTrim(ref edge, bRev3d, ref loop, c2i);
            if (trim != null)
            {
              trim.m_iso = iso;
              trim.m_type = IOnBrepTrim.TYPE.boundary; // This one b-rep face, so all trims are boundary ones.
              trim.set_m_tolerance(0, 0.0); // This simple example is exact - for models with non-exact
              trim.set_m_tolerance(1, 0.0); // data, set tolerance as explained in definition of ON_BrepTrim.
            }
              }

              return loop.m_loop_index;
        }
        private static int MakeTrimmingLoop(ref OnBrep brep,        // returns index of loop
                                            ref OnBrepFace face,    // face loop is on
                                            int v0, int v1, int v2, // Indices of corner vertices listed in A,B,C order
                                            int e0,                 // index of first edge
                                            int e0_dir,             // orientation of edge
                                            int e1,                 // index second edgee
                                            int e1_dir,             // orientation of edge
                                            int e2,                 // index third edge
                                            int e2_dir              // orientation of edge
                                            )
        {
            OnSurface srf = brep.m_S[face.m_si];

            //Create new loop
            OnBrepLoop loop = brep.NewLoop(IOnBrepLoop.TYPE.outer, ref face);

            // Create trimming curves running counter clockwise around the surface's domain.
            // Note that trims of outer loops run counter clockwise while trims of inner loops (holes) run anti-clockwise.
            // Also note that when trims locate on surface N,S,E or W ends, then trim_iso becomes N_iso, S_iso, E_iso and W_iso respectfully.
            // While if trim is parallel to surface N,S or E,W, then trim is becomes y_iso and x_iso respectfully.

            // Start at the south side
            OnCurve c2;
            int     c2i, ei = 0;
            bool    bRev3d = false;

            IOnSurface.ISO iso = IOnSurface.ISO.not_iso;

            for (int side = 0; side < 3; side++)
            {
                // side: 0=south, 1=east, 2=north, 3=west

                c2 = CreateTrimmingCurve(srf, side);

                //Add trimming curve to brep trmming curves array
                c2i = brep.m_C2.Count();
                brep.m_C2.Append(c2);

                switch (side)
                {
                case 0: // south
                    ei     = e0;
                    bRev3d = (e0_dir == -1);
                    iso    = IOnSurface.ISO.S_iso;
                    break;

                case 1: // diagonal
                    ei     = e1;
                    bRev3d = (e1_dir == -1);
                    iso    = IOnSurface.ISO.not_iso;
                    break;

                case 2: // diagonal
                    ei     = e2;
                    bRev3d = (e2_dir == -1);
                    iso    = IOnSurface.ISO.not_iso;
                    break;
                }

                //Create new trim topology that references edge, direction reletive to edge, loop and trim curve geometry
                OnBrepEdge edge = brep.m_E[ei];
                OnBrepTrim trim = brep.NewTrim(ref edge, bRev3d, ref loop, c2i);
                if (trim != null)
                {
                    trim.m_iso  = iso;
                    trim.m_type = IOnBrepTrim.TYPE.boundary; // This one b-rep face, so all trims are boundary ones.
                    trim.set_m_tolerance(0, 0.0);            // This simple example is exact - for models with non-exact
                    trim.set_m_tolerance(1, 0.0);            // data, set tolerance as explained in definition of ON_BrepTrim.
                }
            }
            return(loop.m_loop_index);
        }
        /// <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);
        }
        private static int MakeInnerTrimmingLoop(ref OnBrep brep,                        // returns index of loop
                                                 ref OnBrepFace face,                    // face loop is on
                                                 int vSWi, int vSEi, int vNEi, int vNWi, // Indices of hole vertices
                                                 int eSi,                                // index of edge close to south side of surface
                                                 int eS_dir,                             // orientation of edge with respect to surface trim
                                                 int eEi,                                // index of edge close to east side of surface
                                                 int eE_dir,                             // orientation of edge with respect to surface trim
                                                 int eNi,                                // index of edge close to north side of surface
                                                 int eN_dir,                             // orientation of edge with respect to surface trim
                                                 int eWi,                                // index of edge close to west side of surface
                                                 int eW_dir                              // orientation of edge with respect to surface trim
                                                 )
        {
            OnSurface srf = brep.m_S[face.m_si];
            //Create new inner loop
            OnBrepLoop loop = brep.NewLoop(IOnBrepLoop.TYPE.inner, ref face);

            // Create trimming curves running counter clockwise around the surface's domain.
            // Note that trims of outer loops run counter clockwise while trims of inner loops (holes) run clockwise.
            // Also note that when trims locate on surface N,S,E or W ends, then trim_iso becomes N_iso, S_iso, E_iso and W_iso respectfully.
            // While if trim is parallel to surface N,S or E,W, then trim iso becomes y_iso and x_iso respectfully.
            // All other cases, iso is set to not_iso

            // Start near the south side
            OnCurve c2;
            int     c2i, ei = 0;
            bool    bRev3d = false;

            IOnSurface.ISO iso = IOnSurface.ISO.not_iso;

            for (int side = 0; side < 4; side++)
            {
                // side: 0=near south(y_iso), 1=near west(x_iso), 2=near north(y_iso), 3=near east(x_iso)

                //Create trim 2d curve
                c2 = CreateInnerTrimmingCurve(srf, side);

                //Add trimming curve to brep trmming curves array
                c2i = brep.m_C2.Count();
                brep.m_C2.Append(c2);

                switch (side)
                {
                case 0: // near south
                    ei     = eSi;
                    bRev3d = (eS_dir == -1);
                    iso    = IOnSurface.ISO.y_iso;
                    break;

                case 1: // near west
                    ei     = eEi;
                    bRev3d = (eE_dir == -1);
                    iso    = IOnSurface.ISO.x_iso;
                    break;

                case 2: // near north
                    ei     = eNi;
                    bRev3d = (eN_dir == -1);
                    iso    = IOnSurface.ISO.y_iso;
                    break;

                case 3: // near east
                    ei     = eWi;
                    bRev3d = (eW_dir == -1);
                    iso    = IOnSurface.ISO.x_iso;
                    break;
                }

                //Create new trim topology that references edge, direction reletive to edge, loop and trim curve geometry
                OnBrepEdge edge = brep.m_E[ei];
                OnBrepTrim trim = brep.NewTrim(ref edge, bRev3d, ref loop, c2i);
                if (trim != null)
                {
                    trim.m_iso  = iso;
                    trim.m_type = IOnBrepTrim.TYPE.boundary; // This one b-rep face, so all trims are boundary ones.
                    trim.set_m_tolerance(0, 0.0);            // This simple example is exact - for models with non-exact
                    trim.set_m_tolerance(1, 0.0);            // data, set tolerance as explained in definition of ON_BrepTrim.
                }
            }

            return(loop.m_loop_index);
        }