/// <summary> /// Adds a new edge to the end of the edge list. /// </summary> /// <param name="edges">edges to add</param> /// <param name="directions">The direction each of these edges has, related to the face. /// True means that the edge is reversed compared to the counter-clockwise order of the face. /// <para>This argument can be null. In this case, no edge is considered reversed.</para></param> /// <exception cref="ArgumentOutOfRangeException">If tag is unset or non-defined.</exception> internal SubDFace Add(SubDEdge[] edges, bool[] directions) { // private on purpose for now. I'm not happy with how this function is set up in that // you are required to pass parallel arrays of edges and directions. if (edges == null) { throw new ArgumentNullException("edges"); } if (directions == null) { directions = new bool[edges.Length]; } if (edges.Length != directions.Length) { throw new ArgumentOutOfRangeException("directions", "Length of edges and directions must match."); } if (edges.Length < 3) { throw new ArgumentOutOfRangeException("edges", "There must be at least 3 edges in a SubD face."); } //check to make sure all of the edges were created for this subd for (int i = 0; i < edges.Length; i++) { if (edges[i].ParentSubD != m_subd) { throw new Exception("SubD edge must be created for a specific SubD"); } } IntPtr ptr_subd = m_subd.NonConstPointer(); IntPtr ptr_face; uint id = 0; unsafe { IntPtr *block = stackalloc IntPtr[edges.Length]; for (int i = 0; i < edges.Length; i++) { block[i] = edges[i].NonConstPointer(); } var ptr_ptr = new IntPtr(block); ptr_face = UnsafeNativeMethods.ON_SubD_AddFace(ptr_subd, (uint)edges.Length, ptr_ptr, directions, ref id); } //this should never happen... if (ptr_face == IntPtr.Zero) { throw new InvalidOperationException( "Impossible to add this face to this SubD."); } return(new SubDFace(m_subd, ptr_face, id)); }
/// <summary> /// Add a new vertex to the end of the Vertex list. /// </summary> /// <param name="tag">The type of vertex tag, such as smooth or corner.</param> /// <param name="vertex">Location of new vertex.</param> /// <returns>The newly added vertex.</returns> /// <exception cref="ArgumentOutOfRangeException">If tag is unset or non-defined.</exception> /// <since>7.0</since> public SubDVertex Add(SubDVertexTag tag, Point3d vertex) { if (!SubD.IsSubDVertexTagDefined(tag)) { throw new ArgumentOutOfRangeException("tag"); } IntPtr ptr_subd = m_subd.NonConstPointer(); uint id = 0; IntPtr ptr_vertex = UnsafeNativeMethods.ON_SubD_AddVertex(ptr_subd, tag, vertex, ref id); if (ptr_vertex != IntPtr.Zero) { return(new SubDVertex(m_subd, ptr_vertex, id)); } return(null); }
/// <summary> /// Add a new edge to the list. /// </summary> /// <param name="tag">The type of edge tag, such as smooth or corner.</param> /// <param name="v0">First vertex.</param> /// <param name="v1">Second vertex.</param> /// <exception cref="ArgumentOutOfRangeException">If tag is unset or non-defined.</exception> /// <since>7.0</since> public SubDEdge Add(SubDEdgeTag tag, SubDVertex v0, SubDVertex v1) { if (!SubD.IsSubDEdgeTagDefined(tag)) { throw new ArgumentOutOfRangeException("tag"); } IntPtr ptr_subd = m_subd.NonConstPointer(); IntPtr v0_ptr = v0.NonConstPointer(); IntPtr v1_ptr = v1.NonConstPointer(); uint id = 0; IntPtr ptr_edge = UnsafeNativeMethods.ON_SubD_AddEdge(ptr_subd, tag, v0_ptr, v1_ptr, ref id); if (ptr_edge != IntPtr.Zero) { return(new SubDEdge(m_subd, ptr_edge, id)); } GC.KeepAlive(v0); GC.KeepAlive(v1); return(null); }