예제 #1
0
        internal virtual IntPtr NonConstPointer()
        {
            if (IntPtr.Zero == m_ptr && m_subobject_index >= 0 && m__parent != null)
            {
                Rhino.Geometry.PolyCurve pc = m__parent as Rhino.Geometry.PolyCurve;
                if (pc != null)
                {
                    IntPtr pPolyCurve = pc.NonConstPointer();
                    IntPtr pThis      = UnsafeNativeMethods.ON_PolyCurve_SegmentCurve(pPolyCurve, m_subobject_index);
                    return(pThis);
                }

                Rhino.Geometry.BrepLoop loop = this as Rhino.Geometry.BrepLoop;
                if (loop != null)
                {
                    IntPtr pBrep = loop.Brep.NonConstPointer();
                    return(UnsafeNativeMethods.ON_BrepLoop_GetPointer(pBrep, loop.LoopIndex));
                }
            }

            NonConstOperation(); // allows cached data to clean up
            return(m_ptr);
        }
예제 #2
0
        internal virtual IntPtr NonConstPointer()
        {
            if (IntPtr.Zero != m_ptr)
            {
                // m_ptr points ot an ON_Object.
                // Repair corruption that causes crashes in breps and meshes.
                // The parameters 0,0 mean:
                // The first 0 paramter = bReplair and means detect but do not repair - so exception handler can see the damaged original information.
                // The second 0 parameter = bSilentError means call C++ ON_ERROR() so a dev running a debug build gets a chance to see
                // the corrupt brep/mesh immediately.
                if (PerformCorruptionTesting && 0 != UnsafeNativeMethods.ON_Object_IsCorrupt(m_ptr, 0, 0))
                {
                    throw new CorruptGeometryException(m_ptr, this);
                }
            }
            else if (m_subobject_index >= 0 && m__parent != null)
            {
                Rhino.Geometry.PolyCurve pc = m__parent as Rhino.Geometry.PolyCurve;
                if (pc != null)
                {
                    IntPtr ptr_polycurve = pc.NonConstPointer();
                    IntPtr ptr_this      = UnsafeNativeMethods.ON_PolyCurve_SegmentCurve(ptr_polycurve, m_subobject_index);
                    return(ptr_this);
                }

                Rhino.Geometry.BrepLoop loop = this as Rhino.Geometry.BrepLoop;
                if (loop != null)
                {
                    IntPtr ptr_brep = loop.Brep.NonConstPointer();
                    return(UnsafeNativeMethods.ON_BrepLoop_GetPointer(ptr_brep, loop.LoopIndex));
                }
            }

            NonConstOperation(); // allows cached data to clean up
            return(m_ptr);
        }
        /// <summary>
        /// Splits <paramref name="curve"/> as a <see cref="Rhino.Geometry.PolyCurve"/> where knot multiplicity is > degree - 2.
        /// </summary>
        /// <remarks>
        /// Collapses knots using <paramref name="knotTolerance"/>.
        /// </remarks>
        /// <param name="curve"></param>
        /// <param name="polyCurve"></param>
        /// <param name="knotTolerance"></param>
        /// <returns>false if no new polycurve is created.</returns>
        public static bool TryGetPolyCurveC2(this Rhino.Geometry.NurbsCurve curve, out Rhino.Geometry.PolyCurve polyCurve, double knotTolerance = KnotTolerance)
        {
            bool duplicate = false;
            var  spans     = default(List <double>);
            var  degree    = curve.Degree;
            var  knots     = curve.Knots;

            for (int k = degree; k < knots.Count - degree;)
            {
                var multiplicity = KnotMultiplicity(knots, k, knotTolerance, out var _, out var strict);

                if (multiplicity > degree - 2)
                {
                    if (spans is null)
                    {
                        spans = new List <double>();
                    }
                    spans.Add(knots[k]);
                }

                if (!strict)
                {
                    // We are going to modify curve so we need a duplicate here
                    if (!duplicate)
                    {
                        curve     = curve.Duplicate() as Rhino.Geometry.NurbsCurve;
                        duplicate = true;
                    }

                    var excess = multiplicity - knots.KnotMultiplicity(k);

                    // Correct multiplicity in case more than degree knots are snapped here
                    multiplicity = Math.Min(multiplicity, degree);

                    // Insert new knot multiplicity
                    knots.InsertKnot(knots[k], multiplicity);

                    // Remove old knots that do not overlap knots[k]
                    if (excess > 0)
                    {
                        knots.RemoveKnots(k + multiplicity, k + multiplicity + excess);
                    }
                }

                k += multiplicity;
            }

            if (spans is null)
            {
                polyCurve = default;
                return(false);
            }

            polyCurve = new Rhino.Geometry.PolyCurve();
            foreach (var span in curve.Split(spans))
            {
                polyCurve.AppendSegment(span);
            }

            // Split may generate PolyCurves on seams.
            if (curve.IsClosed)
            {
                polyCurve.RemoveNesting();
            }

            return(true);
        }