Ejemplo n.º 1
0
        private BrepTrim GetClosetBrepTrim(BrepTrimList TrimList, Curve Crv)
        {
            foreach (BrepTrim item in TrimList)
            {
                //
                //item.TrimCurve 会出现问题,
                //关于TrimCurve官方的解释如下
                //Gets the Brep.Curves2D 2d curve geometry used by this trim, or null.
                //item.Edge is an 2D Curve
                //
                //这里只对两根线是否相等进行了简单的判断,如果起始点相等,那么就相等,否则不相等
                Curve EdgeCrv = item.Edge.EdgeCurve;

                Point3d TrimSPt = EdgeCrv.PointAtStart;
                Point3d TrimEPt = EdgeCrv.PointAtEnd;

                bool IsMeetEnd = (TrimSPt.EpsilonEquals(Crv.PointAtStart, 10) && TrimEPt.EpsilonEquals(Crv.PointAtEnd, 10)) ||
                                 (TrimSPt.EpsilonEquals(Crv.PointAtEnd, 10) && TrimEPt.EpsilonEquals(Crv.PointAtStart, 10));

                if (IsMeetEnd)
                {
                    return(item);
                }
            }
            return(null);
        }
Ejemplo n.º 2
0
        private Face ByBrepFace(BrepFace ghBrepFace)
        {
            Rhino.Geometry.Surface ghSurface = ghBrepFace.UnderlyingSurface();

            Face untrimmedFace = BySurface(ghSurface);

            BrepLoop     ghOuterLoop = ghBrepFace.OuterLoop;
            Wire         outerWire   = null;
            BrepLoopList ghLoops     = ghBrepFace.Loops;
            List <Wire>  innerWires  = new List <Wire>();

            foreach (BrepLoop ghLoop in ghLoops)
            {
                BrepTrimList ghTrims       = ghLoop.Trims;
                List <Edge>  trimmingEdges = new List <Edge>();
                foreach (BrepTrim ghTrim in ghTrims)
                {
                    BrepEdge ghEdge = ghTrim.Edge;
                    if (ghEdge == null)
                    {
                        continue;
                        //throw new Exception("An invalid Rhino edge is encountered.");
                    }

                    Topology topology = ByCurve(ghEdge.DuplicateCurve());

                    // Edge or Wire?
                    Edge trimmingEdge = topology as Edge;
                    if (trimmingEdge != null)
                    {
                        trimmingEdges.Add(trimmingEdge);
                    }

                    Wire partialTrimmingWire = topology as Wire;
                    if (partialTrimmingWire != null)
                    {
                        List <Edge> partialTrimmingEdges = partialTrimmingWire.Edges;
                        trimmingEdges.AddRange(partialTrimmingEdges);
                    }
                }
                Wire          trimmingWire     = Wire.ByEdges(trimmingEdges);
                List <Vertex> trimmingVertices = trimmingWire.Vertices;

                if (ghLoop == ghOuterLoop)
                {
                    outerWire = trimmingWire;
                }
                else
                {
                    innerWires.Add(trimmingWire);
                }
            }

            Face outerTrimmedFace = Topologic.Utilities.FaceUtility.TrimByWire(untrimmedFace, outerWire, true);
            Face finalFace        = outerTrimmedFace.AddInternalBoundaries(innerWires);

            return(finalFace);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            Surface         Srf       = default(Surface);
            List <Curve>    Crvs      = new List <Curve>();
            List <BrepTrim> TrimsList = new List <BrepTrim>();
            double          Length    = 2;
            bool            IsSmooth  = true;

            if (!DA.GetData(0, ref Srf))
            {
                return;
            }
            if (!DA.GetDataList <Curve>(1, Crvs))
            {
                return;
            }
            if (!DA.GetData(2, ref Length))
            {
                return;
            }
            if (!DA.GetData(3, ref IsSmooth))
            {
                return;
            }


            Brep TempBrep = Srf.ToBrep();

            if (!TempBrep.IsSurface || TempBrep == null)
            {
                this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Unable to extend trimmed surfaces.:line 67");
                return;
            }
            //BrepTrimList is an reference object
            BrepTrimList BrepTrimList = TempBrep.Trims;

            for (int Index = 0; Index < Crvs.Count; Index++)
            {
                BrepTrim TrimItem = this.GetClosetBrepTrim(BrepTrimList, Crvs[Index]);
                TrimsList.Add(TrimItem);
            }
            var TempList = TrimsList.Where(item => item == null || item.TrimType == BrepTrimType.Seam).ToList();

            if (TempList.Count != 0)
            {
                this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Unable to extend trimmed surfaces. line 81");
            }
            ///<summary>
            ///如果输入的Surface为UntrimSurface,那么Extend会对Surface进行延伸,如果输入的Surface为Untrim Surface,Extend
            ///方法就会先对Surface 执行‘untrim’操作,然后再对面进行延伸
            /// </summary>
            for (int Index = 0; Index < TrimsList.Count; Index++)
            {
                Srf = Srf.Extend(TrimsList[Index].IsoStatus, Length, IsSmooth);
            }
            DA.SetData(0, Srf);
        }
Ejemplo n.º 4
0
 internal static void _InitThreadSafe(this BrepTrimList trims)
 {
     lock (trims)
     {
         var count = trims.Count;
         if (count > 0)
         {
             // we take last element and thus init all list - this make our list threadsafe
             var last = trims[count - 1];
         }
     }
 }
Ejemplo n.º 5
0
        /// <summary>
        /// Get index of trim in loop to which it belongs.
        /// Dont use TrimIndex, since it is global index: index of trim in all trims from Brep.
        /// </summary>
        /// <param name="trim"></param>
        /// <param name="loopTrims"></param>
        /// <returns></returns>
        public static int _IndexInLoop(this BrepTrim trim, BrepTrimList loopTrims = null)
        {
            var trims = loopTrims ?? trim.Loop.Trims_ThreadSafe();

            for (int i = 0; i < trims.Count; i++)
            {
                if (trims[i].TrimIndex == trim.TrimIndex)
                {
                    return(i);
                }
            }
            throw new Exception("Cannot find trimindex in mehod: _BrepTrim._IndexInLoop(trim)");
        }
Ejemplo n.º 6
0
        public static List <Point3d[]> _GetTrimControlPoints(this BrepTrimList loopTrims)
        {
            loopTrims._InitThreadSafe();

            var res = new List <Point3d[]>();

            foreach (var trim in loopTrims)
            {
                var points = trim.TrimType == BrepTrimType.Singular
                    ? new[] { trim.PointAtStart, trim.PointAtEnd }
                    : trim._ToNurbsCurve().Points.Select(o => o.Location).ToArray();
                res.Add(points);
            }
            return(res);
        }
Ejemplo n.º 7
0
        public static List <BrepTrim> _SelectNonSingularTrims(this BrepTrimList trims)
        {
            trims._InitThreadSafe();
            var res = new List <BrepTrim>();

            foreach (var trim in trims)
            {
                switch (trim.TrimType)
                {
                case BrepTrimType.Boundary:
                case BrepTrimType.Mated:
                case BrepTrimType.Seam:
                    res.Add(trim);
                    //var edgeLength = trim.Edge.GetLength();
                    //var trimLength = trim.GetLength();
                    //if (edgeLength < 0.0001)
                    //{
                    //    var nothing = 0;
                    //    // do not add very small edges
                    //}
                    //else
                    //{
                    //    trimsUnsorted.Add(trim);
                    //}
                    break;

                case BrepTrimType.Singular:
                    // nothing - dont copy singular trims
                    int i = 0;
                    break;

                default:
                    throw new Exception("Exception: class Object_BrepLoop - Not supported type in trims: " + trim.ObjectType);
                }
            }
            return(res);
        }
Ejemplo n.º 8
0
        public static List <BrepTrim> _SortByCrvs3d(this BrepTrimList trims, out List <bool> trimsReversedFlag, out bool crvs3dHasReversedDirection)
        {
            var reversedDirectionCount = 0;

            trimsReversedFlag = new List <bool>();
            var trimsUnsorted = trims._SelectNonSingularTrims();


            var trimsSorted    = new List <BrepTrim>();
            var searchForIndex = -1;

            //var debugIndexes = new List<int>();
            //var debugIs = new List<int>();
            while (trimsUnsorted.Count > 0)
            {
                bool found      = false;
                int  foundIndex = 0;
                for (var i = 0; i < trimsUnsorted.Count; i++)
                {
                    var trim = trimsUnsorted[i];
                    //var indexStart = trim.Edge.PointAtStart._GetVertexIndex(trim.Brep.Vertices);
                    //var indexEnd = trim.Edge.PointAtEnd._GetVertexIndex(trim.Brep.Vertices);
                    var indexStart = trim.Edge._GetStartVertex().VertexIndex;
                    var indexEnd   = trim.Edge._GetEndVertex().VertexIndex;
                    if (searchForIndex == -1)
                    {
                        searchForIndex = indexStart;
                    }
                    if (!found && (indexStart == searchForIndex || indexEnd == searchForIndex))
                    {
                        found      = true;
                        foundIndex = i;
                        // continue to search for circular crvs - that PointStart == PointEnd
                    }
                    if (indexStart == searchForIndex && indexStart == indexEnd)
                    {
                        found      = true;
                        foundIndex = i;
                        break; //if found circular crv stop search - circular crvs have the highest priority
                    }
                }

                if (found)
                {
                    var trim        = trimsUnsorted[foundIndex];
                    var indexStart  = trim.Edge._GetStartVertex().VertexIndex;
                    var indexEnd    = trim.Edge._GetEndVertex().VertexIndex;
                    var distToStart = trim.Edge.PointAtStart._DistanceTo(trim.Face.PointAt(trim.PointAtStart.X, trim.PointAtStart.Y));
                    var distToEnd   = trim.Edge.PointAtStart._DistanceTo(trim.Face.PointAt(trim.PointAtEnd.X, trim.PointAtEnd.Y));
                    if (distToStart < distToEnd)
                    {
                        reversedDirectionCount--;
                    }
                    if (distToStart > distToEnd)
                    {
                        reversedDirectionCount++;
                    }

                    //debugIndexes.Add(indexStart);
                    //debugIndexes.Add(indexEnd);
                    trimsUnsorted.RemoveAt(foundIndex);
                    //debugIs.Add(foundIndex);
                    trimsSorted.Add(trim);

                    // Detect reversed flag: a) end->start - straight connection b)end->end - reversed connection
                    var straightConnection = (indexStart == searchForIndex);
                    // for circular crvs simple detection if connection is staight doesnt work - so lets do precision calculation
                    if (indexStart == indexEnd)
                    {
                    }
                    if (straightConnection)
                    {
                        trimsReversedFlag.Add(false);
                        searchForIndex = indexEnd;
                    }
                    else
                    {
                        trimsReversedFlag.Add(true);
                        searchForIndex = indexStart;
                    }
                }
                if (!found)
                {
                    throw new Exception(
                              "Exception:  Cannot find next trim! (Issue_SurfaceBad_BadTrim_Singular.SortTrims)");
                }
            }
            crvs3dHasReversedDirection = reversedDirectionCount > 0;
            return(trimsSorted);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Find prev and next trim in same loop.
        ///
        /// </summary>
        /// <param name="trim"></param>
        /// <param name="prevTrim"></param>
        /// <param name="nextTrim"></param>
        /// <param name="loopTrims">Provide this parameter is possible. Speed optimization. If it is not provided - will be calculcated, what takes some time.</param>
        public static void _GetPrevNextTrims(this BrepTrim trim, out BrepTrim prevTrim, out BrepTrim nextTrim, BrepTrimList loopTrims = null)
        {
            var trims = loopTrims ?? trim.Loop.Trims_ThreadSafe();

            for (int i = 0; i < trims.Count; i++)
            {
                if (trims[i].TrimIndex == trim.TrimIndex)
                {
                    var iPrev = (i != 0) ? i - 1 : trims.Count - 1;
                    var iNext = (i != trims.Count - 1) ? i + 1 : 0;
                    prevTrim = trims[iPrev];
                    nextTrim = trims[iNext];
                    return;
                }
            }
            throw new Exception("Cannot find trimindex in mehod: _BrepTrim._GetPrevNextTrims(trim, out prevTrim, out nextTrim)");
        }
Ejemplo n.º 10
0
        public static global::Topologic.Face ToTopologic(this BrepFace brepFace)
        {
            global::Rhino.Geometry.Surface ghSurface = brepFace?.UnderlyingSurface();
            if (ghSurface == null)
            {
                return(null);
            }

            global::Topologic.Face untrimmedFace = ghSurface.ToTopologic();

            BrepLoop     ghOuterLoop = brepFace.OuterLoop;
            Wire         outerWire   = null;
            BrepLoopList ghLoops     = brepFace.Loops;
            List <Wire>  innerWires  = new List <Wire>();

            foreach (BrepLoop ghLoop in ghLoops)
            {
                BrepTrimList ghTrims       = ghLoop.Trims;
                List <Edge>  trimmingEdges = new List <Edge>();
                foreach (BrepTrim ghTrim in ghTrims)
                {
                    BrepEdge ghEdge = ghTrim.Edge;
                    if (ghEdge == null)
                    {
                        continue;
                        //throw new Exception("An invalid Rhino edge is encountered.");
                    }

                    Topology topology = ghEdge.DuplicateCurve().ToTopologic();
                    if (topology == null)
                    {
                        continue;
                    }

                    // Edge or Wire?
                    Edge trimmingEdge = topology as Edge;
                    if (trimmingEdge != null)
                    {
                        trimmingEdges.Add(trimmingEdge);
                    }

                    Wire partialTrimmingWire = topology as Wire;
                    if (partialTrimmingWire != null)
                    {
                        IList <Edge> partialTrimmingEdges = partialTrimmingWire.Edges;
                        trimmingEdges.AddRange(partialTrimmingEdges);
                    }
                }

                Wire trimmingWire = Wire.ByEdges(trimmingEdges);
                if (ghLoop == ghOuterLoop)
                {
                    outerWire = trimmingWire;
                }
                else
                {
                    innerWires.Add(trimmingWire);
                }
            }

            global::Topologic.Face outerTrimmedFace = global::Topologic.Utilities.FaceUtility.TrimByWire(untrimmedFace, outerWire, true);
            global::Topologic.Face finalFace        = outerTrimmedFace.AddInternalBoundaries(innerWires);

            return(finalFace);
        }