internal bool Optimize(MxVector3 vec1, MxVector3 vec2, ref MxVector3 opt) { var diff = vec1 - vec2; var tens = Tensor; var tV2 = tens * vec2; var tDiff = tens * diff; var denom = 2.0 * diff * tDiff; if (denom.IsSqCloseEnoughTo(0.0)) { return(false); } var a = (-2.0 * (Vector * diff) - (diff * tV2) - (vec2 * tDiff)) / (2.0 * (diff * tDiff)); if (a < 0.0) { a = 0.0; } else if (a > 1.0) { a = 1.0; } opt = a * diff + vec2; return(true); }
internal double CheckLocalCompactness(int vertId, double[] vNew) { var n1 = model.Neighbors(vertId); var cMin = 1.0; foreach (var faceId in n1) { if (!model.FaceIsValid(faceId)) { continue; } var face = model.Face(faceId); MxVector3[] fAfter = new MxVector3[3]; for (var i = 0; i < 3; i++) { fAfter[i] = (face[i] == vertId) ? new MxVector3(vNew) : new MxVector3(model.Vertex(face[i])); } var c = MxGeom3d.TriangleCompactness(fAfter[0], fAfter[1], fAfter[2]); if (c < cMin) { cMin = c; } } return(cMin); }
internal static MxVector3 TriangleNormal(MxVector3 v1, MxVector3 v2, MxVector3 v3) { var n = TriangleRawNormal(v1, v2, v3); MxVector3.Unitize(ref n); return(n); }
internal static double TriangleCompactness(MxVector3 v1, MxVector3 v2, MxVector3 v3) { var area = TriangleArea(v1, v2, v3); var denom = MxVector3.NormSquared(v2 - v1) + MxVector3.NormSquared(v3 - v2) + MxVector3.NormSquared(v1 - v3); return (FourRootThree*area/denom); }
internal static MxMatrix4 TranslationMatrix(MxVector3 delta) { return(new MxMatrix4(new MxVector4(1.0, 0.0, 0.0, delta[0]), new MxVector4(0.0, 1.0, 0.0, delta[1]), new MxVector4(0.0, 0.0, 1.0, delta[2]), new MxVector4(0.0, 0.0, 0.0, 1.0))); }
protected void DiscontinuityConstraint(int vertI, int vertJ, List <int> faceList) { foreach (var faceId in faceList) { var orig = new MxVector3(model.Vertex(vertI)); var dest = new MxVector3(model.Vertex(vertJ)); var edge = dest - orig; var nml = new[] { 0.0, 0.0, 0.0 }; model.ComputeFaceNormal(faceId, ref nml); var n = new MxVector3(nml); var n2 = edge ^ n; MxVector3.Unitize(ref n2); var quad = new MxQuadric3(n2, -(n2 * orig)); quad *= BoundaryWeight; if (WeightingPolicy == MxWeighting.Area || WeightingPolicy == MxWeighting.AreaAverage) { quad.Area = MxVector3.Norm(edge); quad *= quad.Area; } quadrics[vertI] += quad; quadrics[vertJ] += quad; } }
internal static double TriangleCompactness(MxVector3 v1, MxVector3 v2, MxVector3 v3) { var area = TriangleArea(v1, v2, v3); var denom = MxVector3.NormSquared(v2 - v1) + MxVector3.NormSquared(v3 - v2) + MxVector3.NormSquared(v1 - v3); return(FourRootThree * area / denom); }
internal double CheckLocalInversion(int vertId, double[] vNew) { var nMin = 1.0; var n1 = model.Neighbors(vertId); foreach (var faceId in n1) { if (!model.FaceIsValid(faceId)) { continue; } var face = model.Face(faceId); var nml = new double[3]; model.ComputeFaceNormal(faceId, ref nml); var nBefore = new MxVector3(nml); var fAfter = new MxVector3[3]; for (var i = 0; i < 3; i++) { fAfter[i] = (face[i] == vertId) ? new MxVector3(vNew) : new MxVector3(model.Vertex(face[i])); } var newNml = MxGeom3d.TriangleNormal(fAfter[0], fAfter[1], fAfter[2]); var delta = nBefore * newNml; if (delta < nMin) { nMin = delta; } } return(nMin); }
internal static MxMatrix4 ScalingMatrix(MxVector3 scale) { return(new MxMatrix4(new MxVector4(scale[0], 0.0, 0.0, 0.0), new MxVector4(0.0, scale[1], 0.0, 0.0), new MxVector4(0.0, 0.0, scale[2], 0.0), new MxVector4(0.0, 0.0, 0.0, 1.0))); }
public static MxVector3 operator *(MxVector3 vec, double scalar) { var newVec = new MxVector3(0.0, 0.0, 0.0); newVec[0] = vec[0]*scalar; newVec[1] = vec[1]*scalar; newVec[2] = vec[2]*scalar; return newVec; }
public static MxVector3 operator +(MxVector3 vec1, MxVector3 vec2) { var newVec = new MxVector3(0.0, 0.0, 0.0); newVec[0] = vec1[0] + vec2[0]; newVec[1] = vec1[1] + vec2[1]; newVec[2] = vec1[2] + vec2[2]; return newVec; }
protected void CollectQuadrics() { foreach (var quad in quadrics) { quad.Clear(); } for (var i = 0; i < model.FaceCount; i++) { var face = model.Face(i); var vert0 = new MxVector3(model.Vertex(face[0])); var vert1 = new MxVector3(model.Vertex(face[1])); var vert2 = new MxVector3(model.Vertex(face[2])); var plane = (WeightingPolicy == MxWeighting.RawNormals) ? MxGeom3d.TriangleRawPlane(vert0, vert1, vert2) : MxGeom3d.TrianglePlane(vert0, vert1, vert2); var quad = new MxQuadric3(plane[0], plane[1], plane[2], plane[3], model.ComputeFaceArea(i)); switch(WeightingPolicy) { case MxWeighting.Angle: { for (int j = 0; j < 3; j++) { var quadJ = new MxQuadric3(quad); quadJ *= model.ComputeCornerAngle(i, j); quadrics[face[j]] += quadJ; } break; } case MxWeighting.Area: { quad *= quad.Area; quadrics[face[0]] += quad; quadrics[face[1]] += quad; quadrics[face[2]] += quad; break; } case MxWeighting.AreaAverage: { quad *= quad.Area; quadrics[face[0]] += quad; quadrics[face[1]] += quad; quadrics[face[2]] += quad; break; } default: { quadrics[face[0]] += quad; quadrics[face[1]] += quad; quadrics[face[2]] += quad; break; } } } }
public static MxVector3 operator -(MxVector3 vec1) { var newVec = new MxVector3(0.0, 0.0, 0.0); newVec[0] = -vec1[0]; newVec[1] = -vec1[1]; newVec[2] = -vec1[2]; return(newVec); }
public static MxVector3 operator *(MxMatrix3 mat1, MxVector3 vec) { var ret = new MxVector3(0.0, 0.0, 0.0); ret[0] = mat1[0] * vec; ret[1] = mat1[1] * vec; ret[2] = mat1[2] * vec; return(ret); }
internal static MxVector3 Cross(MxVector3 u, MxVector3 v) { var ret = new MxVector3(0.0, 0.0, 0.0); ret[0] = u[1] * v[2] - v[1] * u[2]; ret[1] = v[0] * u[2] - u[0] * v[2]; ret[2] = u[0] * v[1] - v[0] * u[1]; return(ret); }
public static MxVector3 operator +(MxVector3 vec1, MxVector3 vec2) { var newVec = new MxVector3(0.0, 0.0, 0.0); newVec[0] = vec1[0] + vec2[0]; newVec[1] = vec1[1] + vec2[1]; newVec[2] = vec1[2] + vec2[2]; return(newVec); }
public static MxVector3 operator *(MxVector3 vec, double scalar) { var newVec = new MxVector3(0.0, 0.0, 0.0); newVec[0] = vec[0] * scalar; newVec[1] = vec[1] * scalar; newVec[2] = vec[2] * scalar; return(newVec); }
internal bool Optimize(ref MxVector3 vec) { var invMat = new MxMatrix3(0.0); var det = MxMatrix3.Invert(Tensor, ref invMat); if (det.IsSqCloseEnoughTo(0.0)) { return(false); } vec = -(invMat * Vector); return(true); }
internal static MxMatrix3 OuterProduct(MxVector3 vec1, MxVector3 vec2) { var mat = new MxMatrix3(0.0); for (var i = 0; i < 3; i++) { for (var j = 0; j < 3; j++) { mat[i, j] = vec1[i] * vec2[j]; } } return(mat); }
internal bool Optimize(MxVector3 vec1, MxVector3 vec2, MxVector3 vec3, ref MxVector3 opt) { var d13 = vec1 - vec3; var d23 = vec2 - vec3; var A = Tensor; var B = Vector; var Ad13 = A * d13; var Ad23 = A * d23; var Av3 = A * vec3; var d13D23 = (d13 * Ad23) + (d23 * Ad13); var v3D13 = (d13 * Av3) + (vec3 * Ad13); var v3D23 = (d23 * Av3) + (vec3 * Ad23); var d23AD23 = d23 * Ad23; var d13AD13 = d13 * Ad13; var denom = d13AD13 * d23AD23 - 2.0 * d13D23; if (denom.IsSqCloseEnoughTo(0.0)) { return(false); } var a = ((d23AD23 * (2.0 * (B * d13) + v3D13)) - (d13D23 * (2.0 * (B * d23) + v3D23))) / -denom; var b = ((d13AD13 * (2.0 * (B * d13) + v3D23)) - (d13D23 * (2.0 * (B * d13) + v3D13))) / -denom; if (a < 0.0) { a = 0.0; } else if (a > 1.0) { a = 1.0; } if (b < 0.0) { b = 0.0; } else if (b > 1.0) { b = 1.0; } opt = a * d13 + b * d23 + vec3; return(true); }
public static MxVector3 operator /(MxVector3 vec, double scalar) { if (scalar.IsCloseEnoughTo(0.0)) { return(vec); } var invScalar = 1.0 / scalar; var newVec = new MxVector3(0.0, 0.0, 0.0); newVec[0] = vec[0] * invScalar; newVec[1] = vec[1] * invScalar; newVec[2] = vec[2] * invScalar; return(newVec); }
internal bool Optimize(ref double x, ref double y, ref double z) { var vec = new MxVector3(0.0, 0.0, 0.0); var success = Optimize(ref vec); if (!success) { return(false); } x = vec[0]; y = vec[1]; z = vec[2]; return(true); }
internal static void Unitize(ref MxVector3 vec) { var denom = vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2]; if (denom.IsSqCloseEnoughTo(0.0)) { return; } denom = Math.Sqrt(denom); var invDenom = 1.0 / denom; vec[0] *= invDenom; vec[1] *= invDenom; vec[2] *= invDenom; }
internal static MxMatrix3 OuterProduct(MxVector3 vec) { var mat = new MxMatrix3(0.0); var x = vec[0]; var y = vec[1]; var z = vec[2]; mat[0, 0] = x * x; mat[0, 1] = x * y; mat[0, 2] = x * z; mat[1, 0] = mat[0, 1]; mat[1, 1] = y * y; mat[1, 2] = y * z; mat[2, 0] = mat[0, 2]; mat[2, 1] = mat[1, 2]; mat[2, 2] = z * z; return(mat); }
internal static MxMatrix4 RotationMatrixRad(double theta, MxVector3 axis) { var cos = Math.Cos(theta); var sin = Math.Sin(theta); var xx = axis[0] * axis[0]; var xy = axis[0] * axis[1]; var xz = axis[0] * axis[2]; var yy = axis[1] * axis[1]; var yz = axis[1] * axis[2]; var zz = axis[2] * axis[2]; var xs = axis[0] * sin; var ys = axis[1] * sin; var zs = axis[2] * sin; return(new MxMatrix4(new MxVector4(xx * (1 - cos) + cos, xy * (1 - cos) - zs, xz * (1 - cos) + ys, 0.0), new MxVector4(xy * (1 - cos) + zs, yy * (1 - cos) + cos, yz * (1 - cos) - xs, 0.0), new MxVector4(xz * (1 - cos) - ys, yz * (1 - cos) + xs, zz * (1 - cos) - cos, 0.0), new MxVector4(0.0, 0.0, 0.0, 1.0))); }
internal static MxMatrix4 LookAtMatrix(MxVector3 from, MxVector3 at, MxVector3 up) { var vUp = new MxVector3(up[0], up[1], up[2]); MxVector3.Unitize(ref vUp); var f = at - from; MxVector3.Unitize(ref f); var s = f ^ vUp; MxVector3.Unitize(ref s); var u = s ^ f; MxVector3.Unitize(ref u); var mat = new MxMatrix4(new MxVector4(s, 0.0), new MxVector4(u, 0.0), new MxVector4(-f, 0.0), new MxVector4(0.0, 0.0, 0.0, 1.0)); return(mat * TranslationMatrix(-from)); }
internal static double TriangleArea(MxVector3 v1, MxVector3 v2, MxVector3 v3) { var vec = TriangleRawNormal(v1, v2, v3); return 0.5*(MxVector3.Norm(vec)); }
internal static MxMatrix4 TranslationMatrix(MxVector3 delta) { return new MxMatrix4(new MxVector4(1.0, 0.0, 0.0, delta[0]), new MxVector4(0.0, 1.0, 0.0, delta[1]), new MxVector4(0.0, 0.0, 1.0, delta[2]), new MxVector4(0.0, 0.0, 0.0, 1.0)); }
internal MxQuadric3(MxVector3 vec, double d, double area = 1.0) : this(vec[0], vec[1], vec[2], d, area) { }
internal bool Optimize(MxVector3 vec1, MxVector3 vec2, MxVector3 vec3, ref MxVector3 opt) { var d13 = vec1 - vec3; var d23 = vec2 - vec3; var A = Tensor; var B = Vector; var Ad13 = A*d13; var Ad23 = A*d23; var Av3 = A*vec3; var d13D23 = (d13*Ad23) + (d23*Ad13); var v3D13 = (d13*Av3) + (vec3*Ad13); var v3D23 = (d23*Av3) + (vec3*Ad23); var d23AD23 = d23*Ad23; var d13AD13 = d13*Ad13; var denom = d13AD13*d23AD23 - 2.0*d13D23; if (denom.IsSqCloseEnoughTo(0.0)) return false; var a = ((d23AD23*(2.0*(B*d13) + v3D13)) - (d13D23*(2.0*(B*d23) + v3D23)))/-denom; var b = ((d13AD13*(2.0*(B*d13) + v3D23)) - (d13D23*(2.0*(B*d13) + v3D13)))/-denom; if (a < 0.0) a = 0.0; else if (a > 1.0) a = 1.0; if (b < 0.0) b = 0.0; else if (b > 1.0) b = 1.0; opt = a*d13 + b*d23 + vec3; return true; }
internal static MxVector3 TriangleRawNormal(MxVector3 v1, MxVector3 v2, MxVector3 v3) { return MxVector3.Cross(v2 - v1, v3 - v1); }
internal void ComputeTargetPlacement(MxQSlimEdge info) { var i = info.V1; var j = info.V2; var Qi = quadrics[i]; var Qj = quadrics[j]; var Q = Qi + Qj; var eMin = 0.0; if (PlacementPolicy == MxPlacement.Optimal && Q.Optimize(ref info.vNew[0], ref info.vNew[1], ref info.vNew[2])) { eMin = Q.Evaluate(info.vNew); } else { var vi = new MxVector3(model.Vertex(i)); var vj = new MxVector3(model.Vertex(j)); var best = new MxVector3(0.0, 0.0, 0.0); if (PlacementPolicy == MxPlacement.Line && Q.Optimize(vi, vj, ref best)) { eMin = Q.Evaluate(best); } else { var ei = Q.Evaluate(vi); var ej = Q.Evaluate(vj); if (ei < ej) { eMin = ei; best = vi; } else { eMin = ej; best = vj; } if (PlacementPolicy == MxPlacement.EndOrMid) { var mid = (vi + vj)*0.5; var eMid = Q.Evaluate(mid); if (eMid < eMin) { eMin = eMid; best = mid; } } } info.vNew[0] = best[0]; info.vNew[1] = best[1]; info.vNew[2] = best[2]; } if (WeightingPolicy == MxWeighting.AreaAverage) { eMin /= Q.Area; } info.HeapKey = (float)(-eMin); }
internal void ComputeFaceInfo(int faceId) { var info = faceInfo[faceId]; info.FaceId = faceId; var i = model.Face(faceId)[0]; var j = model.Face(faceId)[1]; var k = model.Face(faceId)[2]; var Qi = quadrics[i]; var Qj = quadrics[j]; var Qk = quadrics[k]; var Q = Qi + Qj + Qk; if (PlacementPolicy == MxPlacement.Optimal && Q.Optimize(ref info.vNew[0], ref info.vNew[1], ref info.vNew[2])) { info.HeapKey = (float)-Q.Evaluate(info.vNew); } else { var v1 = new MxVector3(model.Vertex(i)); var v2 = new MxVector3(model.Vertex(j)); var v3 = new MxVector3(model.Vertex(k)); var e1 = Q.Evaluate(v1); var e2 = Q.Evaluate(v2); var e3 = Q.Evaluate(v3); MxVector3 best; double eMin; if (e1 <= e2 && e1 <= e3) { eMin = e1; best = v1; } else if (e2 <= e1 && e2 <= e3) { eMin = e2; best = v2; } else { eMin = e3; best = v3; } info.vNew[0] = best[0]; info.vNew[1] = best[1]; info.vNew[2] = best[2]; info.HeapKey = (float)(-eMin); } if (WeightingPolicy == MxWeighting.AreaAverage) { info.HeapKey = (float)(info.HeapKey/Q.Area); } if (info.IsInHeap) heap.Update(info); else heap.Insert(info); }
internal static MxMatrix4 RotationMatrixDeg(double theta, MxVector3 axis) { return RotationMatrixRad(theta*Math.PI/180.0, axis); }
internal static void Unitize(ref MxVector3 vec) { var denom = vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2]; if (denom.IsSqCloseEnoughTo(0.0)) return; denom = Math.Sqrt(denom); var invDenom = 1.0 / denom; vec[0] *= invDenom; vec[1] *= invDenom; vec[2] *= invDenom; }
internal static double Norm(MxVector3 u) { return Math.Sqrt(NormSquared(u)); }
public static MxVector3 operator /(MxVector3 vec, double scalar) { if (scalar.IsCloseEnoughTo(0.0)) return vec; var invScalar = 1.0/scalar; var newVec = new MxVector3(0.0, 0.0, 0.0); newVec[0] = vec[0]*invScalar; newVec[1] = vec[1]*invScalar; newVec[2] = vec[2]*invScalar; return newVec; }
internal static MxVector3 TriangleNormal(MxVector3 v1, MxVector3 v2, MxVector3 v3) { var n = TriangleRawNormal(v1, v2, v3); MxVector3.Unitize(ref n); return n; }
internal MxMatrix3(MxVector3 row0, MxVector3 row1, MxVector3 row2) { rows[0] = row0; rows[1] = row1; rows[2] = row2; }
internal static double NormSquared(MxVector3 u) { return(u * u); }
internal static double Norm(MxVector3 u) { return(Math.Sqrt(NormSquared(u))); }
internal static MxMatrix4 LookAtMatrix(MxVector3 from, MxVector3 at, MxVector3 up) { var vUp = new MxVector3(up[0], up[1], up[2]); MxVector3.Unitize(ref vUp); var f = at - from; MxVector3.Unitize(ref f); var s = f ^ vUp; MxVector3.Unitize(ref s); var u = s ^ f; MxVector3.Unitize(ref u); var mat = new MxMatrix4(new MxVector4(s, 0.0), new MxVector4(u, 0.0), new MxVector4(-f, 0.0), new MxVector4(0.0, 0.0, 0.0, 1.0)); return (mat*TranslationMatrix(-from)); }
public MxVector4(MxVector3 vec3, double w) : this(vec3[0], vec3[1], vec3[2], w) { }
internal double CheckLocalInversion(int vertId, double[] vNew) { var nMin = 1.0; var n1 = model.Neighbors(vertId); foreach (var faceId in n1) { if (!model.FaceIsValid(faceId)) continue; var face = model.Face(faceId); var nml = new double[3]; model.ComputeFaceNormal(faceId, ref nml); var nBefore = new MxVector3(nml); var fAfter = new MxVector3[3]; for (var i = 0; i < 3; i++) { fAfter[i] = (face[i] == vertId) ? new MxVector3(vNew) : new MxVector3(model.Vertex(face[i])); } var newNml = MxGeom3d.TriangleNormal(fAfter[0], fAfter[1], fAfter[2]); var delta = nBefore*newNml; if (delta < nMin) nMin = delta; } return nMin; }
internal bool Optimize(MxVector3 vec1, MxVector3 vec2, ref MxVector3 opt) { var diff = vec1 - vec2; var tens = Tensor; var tV2 = tens*vec2; var tDiff = tens*diff; var denom = 2.0*diff*tDiff; if (denom.IsSqCloseEnoughTo(0.0)) return false; var a = (-2.0*(Vector*diff) - (diff*tV2) - (vec2*tDiff))/(2.0*(diff*tDiff)); if (a < 0.0) a = 0.0; else if (a > 1.0) a = 1.0; opt = a*diff + vec2; return true; }
internal static MxVector4 TriangleRawPlane(MxVector3 v1, MxVector3 v2, MxVector3 v3) { var n = TriangleRawNormal(v1, v2, v3); return new MxVector4(n, -(n*v1)); }
internal static MxVector3 Cross(MxVector3 u, MxVector3 v) { var ret = new MxVector3(0.0, 0.0, 0.0); ret[0] = u[1] * v[2] - v[1] * u[2]; ret[1] = v[0] * u[2] - u[0] * v[2]; ret[2] = u[0] * v[1] - v[0] * u[1]; return ret; }
internal static MxMatrix4 ScalingMatrix(MxVector3 scale) { return new MxMatrix4(new MxVector4(scale[0], 0.0, 0.0, 0.0), new MxVector4(0.0, scale[1], 0.0, 0.0), new MxVector4(0.0, 0.0, scale[2], 0.0), new MxVector4(0.0, 0.0, 0.0, 1.0)); }
internal static double NormSquared(MxVector3 u) { return (u*u); }
internal double Evaluate(MxVector3 vec) { return Evaluate(vec[0], vec[1], vec[2]); }
internal static MxMatrix4 RotationMatrixRad(double theta, MxVector3 axis) { var cos = Math.Cos(theta); var sin = Math.Sin(theta); var xx = axis[0]*axis[0]; var xy = axis[0]*axis[1]; var xz = axis[0]*axis[2]; var yy = axis[1]*axis[1]; var yz = axis[1]*axis[2]; var zz = axis[2]*axis[2]; var xs = axis[0]*sin; var ys = axis[1]*sin; var zs = axis[2]*sin; return new MxMatrix4(new MxVector4(xx*(1 - cos) + cos, xy*(1 - cos) - zs, xz*(1 - cos) + ys, 0.0), new MxVector4(xy*(1 - cos) + zs, yy*(1 - cos) + cos, yz*(1 - cos) - xs, 0.0), new MxVector4(xz*(1 - cos) - ys, yz*(1 - cos) + xs, zz*(1 - cos) - cos, 0.0), new MxVector4(0.0, 0.0, 0.0, 1.0)); }
internal bool Optimize(ref MxVector3 vec) { var invMat = new MxMatrix3(0.0); var det = MxMatrix3.Invert(Tensor, ref invMat); if (det.IsSqCloseEnoughTo(0.0)) return false; vec = -(invMat*Vector); return true; }
public static MxVector3 operator -(MxVector3 vec1) { var newVec = new MxVector3(0.0, 0.0, 0.0); newVec[0] = -vec1[0]; newVec[1] = -vec1[1]; newVec[2] = -vec1[2]; return newVec; }
internal bool Optimize(ref double x, ref double y, ref double z) { var vec = new MxVector3(0.0, 0.0, 0.0); var success = Optimize(ref vec); if (!success) return false; x = vec[0]; y = vec[1]; z = vec[2]; return true; }
internal MxMatrix3(MxMatrix3 mat3) { rows[0] = new MxVector3((mat3[0])[0], (mat3[0])[1], (mat3[0])[2]); rows[1] = new MxVector3((mat3[1])[0], (mat3[1])[1], (mat3[1])[2]); rows[2] = new MxVector3((mat3[2])[0], (mat3[2])[1], (mat3[2])[2]); }
internal double CheckLocalCompactness(int vertId, double[] vNew) { var n1 = model.Neighbors(vertId); var cMin = 1.0; foreach (var faceId in n1) { if (!model.FaceIsValid(faceId)) continue; var face = model.Face(faceId); MxVector3[] fAfter = new MxVector3[3]; for (var i = 0; i < 3; i++) { fAfter[i] = (face[i] == vertId) ? new MxVector3(vNew) : new MxVector3(model.Vertex(face[i])); } var c = MxGeom3d.TriangleCompactness(fAfter[0], fAfter[1], fAfter[2]); if (c < cMin) cMin = c; } return cMin; }
internal static MxMatrix4 RotationMatrixDeg(double theta, MxVector3 axis) { return(RotationMatrixRad(theta * Math.PI / 180.0, axis)); }
internal static MxMatrix3 RowExtend(MxVector3 vec) { return(new MxMatrix3(vec, vec, vec)); }
internal void ComputeFaceInfo(int faceId) { var info = faceInfo[faceId]; info.FaceId = faceId; var i = model.Face(faceId)[0]; var j = model.Face(faceId)[1]; var k = model.Face(faceId)[2]; var Qi = quadrics[i]; var Qj = quadrics[j]; var Qk = quadrics[k]; var Q = Qi + Qj + Qk; if (PlacementPolicy == MxPlacement.Optimal && Q.Optimize(ref info.vNew[0], ref info.vNew[1], ref info.vNew[2])) { info.HeapKey = (float)-Q.Evaluate(info.vNew); } else { var v1 = new MxVector3(model.Vertex(i)); var v2 = new MxVector3(model.Vertex(j)); var v3 = new MxVector3(model.Vertex(k)); var e1 = Q.Evaluate(v1); var e2 = Q.Evaluate(v2); var e3 = Q.Evaluate(v3); MxVector3 best; double eMin; if (e1 <= e2 && e1 <= e3) { eMin = e1; best = v1; } else if (e2 <= e1 && e2 <= e3) { eMin = e2; best = v2; } else { eMin = e3; best = v3; } info.vNew[0] = best[0]; info.vNew[1] = best[1]; info.vNew[2] = best[2]; info.HeapKey = (float)(-eMin); } if (WeightingPolicy == MxWeighting.AreaAverage) { info.HeapKey = (float)(info.HeapKey / Q.Area); } if (info.IsInHeap) { heap.Update(info); } else { heap.Insert(info); } }
internal static MxMatrix3 Diag(MxVector3 vec) { return(new MxMatrix3(new MxVector3(vec[0], 0.0, 0.0), new MxVector3(0.0, vec[1], 0.0), new MxVector3(0.0, 0.0, vec[2]))); }