public TopoVertex(int _id, RHVector3 _pos, Matrix4 trans) { id = _id; pos = new RHVector3( _pos.x * trans.Column0.X + _pos.y * trans.Column0.Y + _pos.z * trans.Column0.Z + trans.Column0.W, _pos.x * trans.Column1.X + _pos.y * trans.Column1.Y + _pos.z * trans.Column1.Z + trans.Column1.W, _pos.x * trans.Column2.X + _pos.y * trans.Column2.Y + _pos.z * trans.Column2.Z + trans.Column2.W ); }
public bool ProjectPoint(RHVector3 p, out double lambda, RHVector3 pProjected) { RHVector3 u = v2.pos.Subtract(v1.pos); lambda = p.Subtract(v1.pos).ScalarProduct(u) / u.ScalarProduct(u); pProjected.x = v1.pos.x + lambda * u.x; pProjected.y = v1.pos.y + lambda * u.y; pProjected.z = v1.pos.z + lambda * u.z; return(lambda >= 0 && lambda <= 1); }
//<Carson(Taipei)><11-23-2018><Modified> public TopoTriangle(TopoVertex v1, TopoVertex v2, TopoVertex v3, double nx, double ny, double nz, int index1, int index2, int index3) { vertices[0] = v1; vertices[1] = v2; vertices[2] = v3; normal = new RHVector3(nx, ny, nz); //indices[0] = index1 - 1; //indices[1] = index2 - 1; //indices[2] = index3 - 1; }
public double ScalarProduct(RHVector3 vector) { //try //{ return(x * vector.x + y * vector.y + z * vector.z); //} //catch(System.NullReferenceException) //{ // return x; //} }
/// <summary> /// Checks if all vertices are colinear preventing a normal computation. If point are coliniear the center vertex is /// moved in the direction of the edge to allow normal computations. /// </summary> /// <returns></returns> public bool CheckIfColinear() { RHVector3 d1 = vertices[1].pos.Subtract(vertices[0].pos); RHVector3 d2 = vertices[2].pos.Subtract(vertices[1].pos); double angle = d1.Angle(d2); if (angle > 0.001 && angle < Math.PI - 0.001) { return(false); } return(true); }
public void RecomputeNormal() { try { RHVector3 d1 = vertices[1].pos.Subtract(vertices[0].pos); RHVector3 d2 = vertices[2].pos.Subtract(vertices[1].pos); normal = d1.CrossProduct(d2); normal.NormalizeSafe(); } catch (System.NullReferenceException) { } }
public RHVector3 Subtract(RHVector3 vector) { //try //{ return(new RHVector3(x - vector.x, y - vector.y, z - vector.z)); //} //catch(System.OutOfMemoryException) //{ // throw new System.OutOfMemoryException(); // System.Windows.Forms.MessageBox.Show("Error(" + "Load file failed" + "): " + "Load file failed."); // GC.Collect(); //} }
//<><><> //--- MODEL_SLA public override bool Equals(object obj) { RHVector3 compare = obj as RHVector3; if (x == compare.x && y == compare.y && z == compare.z) { return(true); } else { return(false); } }
//<><><> //<Carson(Taipei)><04-09-2019><Modifed - flat shading> public void AddTriangleForFlat(RHVector3 v1, RHVector3 v2, RHVector3 v3) { Vector3[] vv = new Vector3[3] { v1.asVector3(), v2.asVector3(), v3.asVector3() }; Vector3 normal = calculateNormal(vv[0], vv[1], vv[2]); for (int i = 0; i < 3; ++i) { glTriangles[tmpvar_nTriangles * 3 + i] = tmpvar_vertList.Count; tmpvar_normalList.Add(normal); tmpvar_vertList.Add(vv[i]); } tmpvar_nTriangles++; }
//<><><> //public void Add(TopoVertex vertex,int level) //{ // Int64 temp = Convert.ToInt64(Math.Floor(vertex.pos.x * 100000)) * 5915587277 + Convert.ToInt64(Math.Floor(vertex.pos.y * 100000)) * 1500450271 + Convert.ToInt64(Math.Floor(vertex.pos.z * 100000)) * 3267000013; // if (hash[temp] == null) // { // hash.Add(temp, count); // v.Add(vertex); // count++; // } //} public TopoVertex SearchPoint(RHVector3 vertex) { Int64 temp = Convert.ToInt64(Math.Floor(vertex.x * 100000)) * 5915587277 + Convert.ToInt64(Math.Floor(vertex.y * 100000)) * 1500450271 + Convert.ToInt64(Math.Floor(vertex.z * 100000)) * 3267000013; if (hash[temp] != null) { int idx = Convert.ToInt32(hash[temp]); int listidx = (idx >> 11); int idxinlist = (idx & 0x7FF); return(v[listidx][idxinlist]); } else { return(null); } }
public RHVector3 CrossProduct(RHVector3 vector) { //try //{ return(new RHVector3( y * vector.z - z * vector.y, z * vector.x - x * vector.z, x * vector.y - y * vector.x)); //} //catch(System.OutOfMemoryException) //{ // return null; // //System.Windows.Forms.MessageBox.Show("Error(" + "Load file failed" + "): " + "Load file failed."); // GC.Collect(); //} }
public double alphaBeta; // Sum of dihedral angles to a virtual shared triangle public TopoEdgePair(TopoEdge _edgeA, TopoEdge _edgeB) { edgeA = _edgeA; edgeB = _edgeB; RHVector3 sharedPoint = null; RHVector3 p1 = null, p2 = null; if (edgeA.v1 == edgeB.v1) { sharedPoint = edgeA.v1.pos; p1 = edgeA.v2.pos; p2 = edgeB.v2.pos; } else if (edgeA.v1 == edgeB.v2) { sharedPoint = edgeA.v1.pos; p1 = edgeA.v2.pos; p2 = edgeB.v1.pos; } else if (edgeA.v2 == edgeB.v1) { sharedPoint = edgeA.v1.pos; p1 = edgeA.v1.pos; p2 = edgeB.v2.pos; } else if (edgeA.v2 == edgeB.v2) { sharedPoint = edgeA.v2.pos; p1 = edgeA.v1.pos; p2 = edgeB.v1.pos; } RHVector3 d1 = p1.Subtract(sharedPoint); RHVector3 d2 = p2.Subtract(sharedPoint); RHVector3 normal = d1.CrossProduct(d2); normal.NormalizeSafe(); //alphaBeta = normal.AngleForNormalizedVectors(edgeA.faces.First.Value.normal) + normal.AngleForNormalizedVectors(edgeB.faces.First.Value.normal); //if (alphaBeta > Math.PI) // normal was wrong direction //alphaBeta = 2 * Math.PI - alphaBeta; }
//--- MODEL_SLA // milton // 實作論文的方法 - Fast, Minimum Storage RayTriangle Intersection // t => delta, 如果有打到物體,t>0,否則t<0 public bool IntersectsLineTest(RHVector3 orig, RHVector3 dir, out double t, out double u, out double v) { t = u = v = 0; //Debug.WriteLine("IntersectsLine orig " + orig + " dir " + dir ); //Debug.WriteLine("IntersectsLine ver1 " + vertices[0].pos + " ver2 " + vertices[1].pos + " ver3 " + vertices[2].pos); RHVector3 vert0 = vertices[0].pos; /* find vectors for two edges sharing vert0 * SUB(edge1, vert1, vert0) * SUB(edge2, vert2, vert0) */ RHVector3 edge1 = vertices[1].pos.Subtract(vert0); RHVector3 edge2 = vertices[2].pos.Subtract(vert0); /* begin calculating determinant - also used to calculate U parameter * CROSS(pvec, dir, edge2)*/ RHVector3 pvec = dir.CrossProduct(edge2); /* if determinant is near zero, ray lies in plane of triangle * det = DOT(edge1, pvec)*/ double det = edge1.ScalarProduct(pvec); //Debug.WriteLine("IntersectsLine det " + det); /* define TEST_CULL if culling is desired * if (det < EPSILON)return 0*/ if (det < 0.000001) { return(false); } /* calculate distance from vert0 to ray origin * SUB(tvec, orig, vert0)*/ RHVector3 tvec = orig.Subtract(vert0); //Debug.WriteLine("IntersectsLine tvec " + tvec); /* calculate U parameter and test bounds * u = DOT(tvec, pvec)*/ u = tvec.ScalarProduct(pvec); /*if (*u < 0.0 || *u > det) return 0;*/ //Debug.WriteLine("IntersectsLine u " + u); if (u < 0 || u > det) { return(false); } /* prepare to test V parameter * CROSS(qvec, tvec, edge1)*/ RHVector3 qvec = tvec.CrossProduct(edge1); /* calculate V parameter and test bounds * v = DOT(dir, qvec)*/ v = dir.ScalarProduct(qvec); //Debug.WriteLine("IntersectsLine v " + v); /*if (*v < 0.0 || *u + *v > det) return 0*/ if (v < 0 || (u + v) > det) { return(false); } /* calculate t, scale parameters, ray intersects triangle * t = DOT(edge2, qvec) * inv_det = 1.0 / det * t *= inv_det * u *= inv_det * v *= inv_det*/ double inv_det = 1.0 / det; t = edge2.ScalarProduct(qvec); t *= inv_det; u *= inv_det; v *= inv_det; return(true); }
public double distance(RHVector3 vertex) { return(pos.Distance(vertex)); }
public void SubtractInternal(RHVector3 vector) { x -= vector.x; y -= vector.y; z -= vector.z; }
public void AddInternal(RHVector3 vector) { x += vector.x; y += vector.y; z += vector.z; }
public RHVector3(RHVector3 orig) { x = orig.x; y = orig.y; z = orig.z; }
public RHVector3 Add(RHVector3 vector) { return(new RHVector3(x + vector.x, y + vector.y, z + vector.z)); }
public double Angle(RHVector3 direction) { return(Math.Acos(ScalarProduct(direction) / (Length * direction.Length))); }
//--- public double DistanceToPlane(RHVector3 pos) { double d = vertices[0].pos.ScalarProduct(normal); return(pos.ScalarProduct(normal) - d); }
public double AngleForNormalizedVectors(RHVector3 direction) { return(Math.Acos(ScalarProduct(direction))); }
public double VertexDistance(RHVector3 v) { return(v.x * normal.x + v.y * normal.y + v.z * normal.z - d); }
public void addIntersectionToSubmesh(Submesh mesh, TopoTriangle triangle, bool addEdges, int color) { int[] outside = new int[3]; int[] inside = new int[3]; int nOutside = 0, nInside = 0; int i; for (i = 0; i < 3; i++) { if (VertexDistance(triangle.vertices[i].pos) > 0) { outside[nOutside++] = i; } else { inside[nInside++] = i; } } if (nOutside != 1 && nOutside != 2) { return; } RHVector3[] intersections = new RHVector3[3]; int nIntersections = 0; for (int iInside = 0; iInside < nInside; iInside++) { for (int iOutside = 0; iOutside < nOutside; iOutside++) { RHVector3 v1 = triangle.vertices[inside[iInside]].pos; RHVector3 v2 = triangle.vertices[outside[iOutside]].pos; double dist1 = VertexDistance(v1); double dist2 = VertexDistance(v2); double pos = Math.Abs(dist1) / Math.Abs(dist2 - dist1); intersections[nIntersections++] = new RHVector3( v1.x + pos * (v2.x - v1.x), v1.y + pos * (v2.y - v1.y), v1.z + pos * (v2.z - v1.z) ); } } if (nInside == 2) { if (outside[0] == 1) { mesh.AddTriangle(triangle.vertices[inside[1]].pos, triangle.vertices[inside[0]].pos, intersections[1], color); mesh.AddTriangle(triangle.vertices[inside[0]].pos, intersections[0], intersections[1], color); } else { mesh.AddTriangle(triangle.vertices[inside[0]].pos, triangle.vertices[inside[1]].pos, intersections[0], color); mesh.AddTriangle(triangle.vertices[inside[1]].pos, intersections[1], intersections[0], color); } } else { if (inside[0] == 1) { mesh.AddTriangle(triangle.vertices[inside[0]].pos, intersections[1], intersections[0], color); } else { mesh.AddTriangle(triangle.vertices[inside[0]].pos, intersections[0], intersections[1], color); } } /*if (addEdges) * { * if (nInside == 2) * { * mesh.AddEdge(triangle.vertices[inside[0]].pos, triangle.vertices[inside[1]].pos, triangle.edges[0].connectedFaces == 2 ? Submesh.MESHCOLOR_EDGE : Submesh.MESHCOLOR_ERROREDGE); * mesh.AddEdge(triangle.vertices[inside[0]].pos, intersections[0], triangle.edges[1].connectedFaces == 2 ? Submesh.MESHCOLOR_EDGE : Submesh.MESHCOLOR_ERROREDGE); * mesh.AddEdge(triangle.vertices[inside[1]].pos, intersections[1], triangle.edges[2].connectedFaces == 2 ? Submesh.MESHCOLOR_EDGE : Submesh.MESHCOLOR_ERROREDGE); * } * else * { * for (int iInter = 0; iInter < nIntersections; iInter++) * { * mesh.AddEdge(triangle.vertices[inside[0]].pos, intersections[iInter], triangle.edges[(inside[0]+2*iInter) % 3].connectedFaces == 2 ? Submesh.MESHCOLOR_EDGE : Submesh.MESHCOLOR_ERROREDGE); * } * } * }*/ if (nIntersections == 2) { mesh.AddEdge(intersections[0], intersections[1], Submesh.MESHCOLOR_CUT_EDGE); } }
public void StoreMinimum(RHVector3 vec) { x = Math.Min(x, vec.x); y = Math.Min(y, vec.y); z = Math.Min(z, vec.z); }
public TopoPlane(RHVector3 _normal, RHVector3 pointOnPlane) { normal = new RHVector3(_normal); normal.NormalizeSafe(); d = pointOnPlane.ScalarProduct(normal); }
public void StoreMaximum(RHVector3 vec) { x = Math.Max(x, vec.x); y = Math.Max(y, vec.y); z = Math.Max(z, vec.z); }
public TopoVertex(int _id, RHVector3 _pos) { id = _id; pos = _pos; }