/// <summary> /// Searches for locations where the distance from <i>a mesh in one set</i> of meshes /// is less than distance to <i>another mesh in a second set</i> of meshes. /// </summary> /// <param name="setA">The first set of meshes.</param> /// <param name="setB">The second set of meshes.</param> /// <param name="distance">The largest distance at which there is a clash. /// All values smaller than this cause a clash as well.</param> /// <param name="maxEventCount">The maximum number of clash objects.</param> /// <returns>An array of clash objects.</returns> public static MeshClash[] Search(IEnumerable <Mesh> setA, IEnumerable <Mesh> setB, double distance, int maxEventCount) { IList <Mesh> _setA = setA as IList <Mesh> ?? new List <Mesh>(setA); IList <Mesh> _setB = setB as IList <Mesh> ?? new List <Mesh>(setB); Rhino.Runtime.InteropWrappers.SimpleArrayMeshPointer meshes_a = new Runtime.InteropWrappers.SimpleArrayMeshPointer(); foreach (Mesh m in setA) { meshes_a.Add(m, true); } Rhino.Runtime.InteropWrappers.SimpleArrayMeshPointer meshes_b = new Runtime.InteropWrappers.SimpleArrayMeshPointer(); foreach (Mesh m in setB) { meshes_b.Add(m, true); } IntPtr pClashEventList = UnsafeNativeMethods.ON_SimpleArray_ClashEvent_New(); IntPtr pMeshesA = meshes_a.ConstPointer(); IntPtr pMeshesB = meshes_b.ConstPointer(); int count = UnsafeNativeMethods.ONC_MeshClashSearch(pMeshesA, pMeshesB, distance, maxEventCount, true, pClashEventList); MeshClash[] rc = new MeshClash[count]; Point3d pt = new Point3d(); int indexA = 0; int indexB = 0; double radius = distance / 2.0; for (int i = 0; i < count; i++) { MeshClash mc = new MeshClash(); UnsafeNativeMethods.ON_SimpleArray_ClashEvent_GetEvent(pClashEventList, i, ref indexA, ref indexB, ref pt); if (indexA >= 0 && indexB >= 0) { mc.m_mesh_a = _setA[indexA]; mc.m_mesh_b = _setB[indexB]; mc.m_P = pt; mc.m_radius = radius; } rc[i] = mc; } meshes_a.Dispose(); meshes_b.Dispose(); UnsafeNativeMethods.ON_SimpleArray_ClashEvent_Delete(pClashEventList); GC.KeepAlive(setA); GC.KeepAlive(setB); return(rc); }
/// <summary> /// Searches for locations where the distance from <i>a mesh in one set</i> of meshes /// is less than distance to <i>another mesh in a second set</i> of meshes. /// </summary> /// <param name="setA">The first set of meshes.</param> /// <param name="setB">The second set of meshes.</param> /// <param name="distance">The largest distance at which there is a clash. /// All values smaller than this cause a clash as well.</param> /// <param name="maxEventCount">The maximum number of clash objects.</param> /// <returns>An array of clash objects.</returns> public static MeshClash[] Search(IEnumerable<Mesh> setA, IEnumerable<Mesh> setB, double distance, int maxEventCount) { IList<Mesh> _setA = setA as IList<Mesh> ?? new List<Mesh>(setA); IList<Mesh> _setB = setB as IList<Mesh> ?? new List<Mesh>(setB); Rhino.Runtime.InteropWrappers.SimpleArrayMeshPointer meshes_a = new Runtime.InteropWrappers.SimpleArrayMeshPointer(); foreach (Mesh m in setA) meshes_a.Add(m, true); Rhino.Runtime.InteropWrappers.SimpleArrayMeshPointer meshes_b = new Runtime.InteropWrappers.SimpleArrayMeshPointer(); foreach (Mesh m in setB) meshes_b.Add(m, true); IntPtr pClashEventList = UnsafeNativeMethods.ON_SimpleArray_ClashEvent_New(); IntPtr pMeshesA = meshes_a.ConstPointer(); IntPtr pMeshesB = meshes_b.ConstPointer(); int count = UnsafeNativeMethods.ONC_MeshClashSearch(pMeshesA, pMeshesB, distance, maxEventCount, true, pClashEventList); MeshClash[] rc = new MeshClash[count]; Point3d pt = new Point3d(); int indexA = 0; int indexB = 0; double radius = distance / 2.0; for (int i = 0; i < count; i++) { MeshClash mc = new MeshClash(); UnsafeNativeMethods.ON_SimpleArray_ClashEvent_GetEvent(pClashEventList, i, ref indexA, ref indexB, ref pt); if (indexA >= 0 && indexB >= 0) { mc.m_mesh_a = _setA[indexA]; mc.m_mesh_b = _setB[indexB]; mc.m_P = pt; mc.m_radius = radius; } rc[i] = mc; } meshes_a.Dispose(); meshes_b.Dispose(); UnsafeNativeMethods.ON_SimpleArray_ClashEvent_Delete(pClashEventList); return rc; }