void RecalculateNormalsInternal(bool updateMesh = true)
        {
            if (m_forceDisableRecalculation)
            {
                return;
            }

            npMeshData tmp = m_npModelData;

            tmp.vertices = m_pointsPredeformed;
            npGenerateNormals(ref tmp, m_normalsPredeformed);

            if (m_skinned)
            {
                npApplySkinning(ref m_npSkinData,
                                IntPtr.Zero, m_normalsPredeformed, IntPtr.Zero,
                                IntPtr.Zero, m_normals, IntPtr.Zero);
            }

            if (updateMesh)
            {
                m_meshTarget.SetNormals(m_normalsPredeformed.List);
            }
            m_cbNormalsDirty = true;
        }
        void PrepareMirror()
        {
            if (m_settings.mirrorMode == MirrorMode.None)
            {
                return;
            }

            bool needsSetup = false;

            if (m_mirrorRelation == null || m_mirrorRelation.Count != m_points.Count)
            {
                m_mirrorRelation = new PinnedList <int>(m_points.Count);
                needsSetup       = true;
            }
            if (m_prevMirrorMode != m_settings.mirrorMode)
            {
                m_prevMirrorMode = m_settings.mirrorMode;
                needsSetup       = true;
            }

            Vector3 planeNormal = GetMirrorPlane(m_settings.mirrorMode);

            if (needsSetup)
            {
                npMeshData tmp = m_npModelData;
                tmp.vertices = m_pointsBasePredeformed;
                tmp.normals  = m_normalsBasePredeformed;
                if (npBuildMirroringRelation(ref tmp, planeNormal, m_settings.mirrorEpsilon, m_mirrorRelation) == 0)
                {
                    Debug.LogWarning("This mesh seems not symmetric");
                    m_mirrorRelation      = null;
                    m_settings.mirrorMode = MirrorMode.None;
                }
            }
        }
        void RecalculateTangentsInternal(TangentsPrecision precision, bool updateMesh = true)
        {
            if (m_forceDisableRecalculation)
            {
                return;
            }

            if (precision == TangentsPrecision.Precise)
            {
                m_meshTarget.RecalculateTangents();
                m_tangentsPredeformed.LockList(l =>
                {
                    m_meshTarget.GetTangents(l);
                });
            }
            else
            {
                npMeshData tmp = m_npModelData;
                tmp.vertices = m_pointsPredeformed;
                tmp.normals  = m_normalsPredeformed;
                npGenerateTangents(ref tmp, m_tangentsPredeformed);
            }

            if (m_skinned)
            {
                npApplySkinning(ref m_npSkinData,
                                IntPtr.Zero, IntPtr.Zero, m_tangentsPredeformed,
                                IntPtr.Zero, IntPtr.Zero, m_tangents);
            }

            if (updateMesh)
            {
                m_meshTarget.SetTangents(m_tangentsPredeformed.List);
            }
            m_cbTangentsDirty = true;
        }
 [DllImport("VertexTweakerCore")] static extern Vector3 npPickNormal(
     ref npMeshData model, Vector3 pos, int ti);
 [DllImport("VertexTweakerCore")] static extern int npRaycast(
     ref npMeshData model, Vector3 pos, Vector3 dir, ref int tindex, ref float distance);
 [DllImport("VertexTweakerCore")] static extern int npUpdateSelection(
     ref npMeshData model,
     ref Vector3 selection_pos, ref Vector3 selection_normal);
 [DllImport("VertexTweakerCore")] static extern int npSelectRect(
     ref npMeshData model, ref Matrix4x4 viewproj, Vector2 rmin, Vector2 rmax, Vector3 campos, float strength, bool frontfaceOnly);
 [DllImport("VertexTweakerCore")] static extern int npSelectHole(
     ref npMeshData model, float strength, bool clear, bool mask);
 [DllImport("VertexTweakerCore")] static extern void npProjectVertices(
     ref npMeshData model, ref npMeshData target, IntPtr ray_dirs, npProjectVerticesMode mode, float max_distance, int PNT, bool mask);
 [DllImport("VertexTweakerCore")] static extern void npApplyMirroring(
     ref npMeshData model, IntPtr relation, Vector3 plane_normal,
     IntPtr iopoints, IntPtr ionormals, IntPtr iotangents);
 [DllImport("VertexTweakerCore")] static extern int npBuildMirroringRelation(
     ref npMeshData model, Vector3 plane_normal, float epsilon, IntPtr relation);
 [DllImport("VertexTweakerCore")] static extern int npScaleVertices(
     ref npMeshData model, Vector3 amount, Vector3 pivotPos, Quaternion pivotRot, bool mask);
 [DllImport("VertexTweakerCore")] static extern int npMoveVertices(
     ref npMeshData model, Vector3 amount, bool mask);
 [DllImport("VertexTweakerCore")] static extern int npAssignVertices(
     ref npMeshData model, Vector3 value, Matrix4x4 transform, int xyz, bool mask);
 [DllImport("VertexTweakerCore")] static extern bool npPickVertex(
     ref npMeshData model, ref Matrix4x4 viewproj, Vector2 rmin, Vector2 rmax, Vector3 campos, bool frontfaceOnly, ref int vi, ref Vector3 vpos);
 [DllImport("VertexTweakerCore")] static extern int npSelectTriangle(
     ref npMeshData model, Vector3 pos, Vector3 dir, float strength);
 [DllImport("VertexTweakerCore")] static extern void npProjectVerticesDirectional(
     ref npMeshData model, ref npMeshData target, Vector3 ray_dir, npProjectVerticesMode mode, float max_distance, int PNT, bool mask);
 [DllImport("VertexTweakerCore")] static extern int npSelectConnected(
     ref npMeshData model, float strength, bool clear);
 [DllImport("VertexTweakerCore")] static extern int npGenerateTangents(
     ref npMeshData model, IntPtr dst);
 [DllImport("VertexTweakerCore")] static extern int npSelectLasso(
     ref npMeshData model, ref Matrix4x4 viewproj, Vector2[] lasso, int numLassoPoints, Vector3 campos, float strength, bool frontfaceOnly);
 [DllImport("VertexTweakerCore")] static extern int npSelectBrush(
     ref npMeshData model,
     Vector3 pos, float radius, float strength, int num_bsamples, IntPtr bsamples);