public static void print_compare(string prefix, Vector3 v1, g3.Vector3f v2) { double dErr = Math.Abs(v1.x - v2.x) + Math.Abs(v1.y - v2.y) + Math.Abs(v1.z - v2.z); DebugUtil.Log(2, "{0} {1} {2} err {3}", prefix, v1.ToString("F8"), v2.ToString(), dErr); }
override public MeshGenerator Generate() { if (Polygon == null) { Polygon = Polygon2d.MakeCircle(1.0f, 8); } int Slices = Polygon.VertexCount; int nRings = Vertices.Count; int nRingSize = (NoSharedVertices) ? Slices + 1 : Slices; int nCapVertices = (NoSharedVertices) ? Slices + 1 : 1; if (Capped == false || ClosedLoop == true) { nCapVertices = 0; } vertices = new VectorArray3d(nRings * nRingSize + 2 * nCapVertices); uv = new VectorArray2f(vertices.Count); normals = new VectorArray3f(vertices.Count); int quad_strips = ClosedLoop ? (nRings) : (nRings - 1); int nSpanTris = quad_strips * (2 * Slices); int nCapTris = (Capped && ClosedLoop == false) ? 2 * Slices : 0; triangles = new IndexArray3i(nSpanTris + nCapTris); Frame3f fCur = new Frame3f(Frame); Vector3d dv = CurveUtils.GetTangent(Vertices, 0);; fCur.Origin = (Vector3f)Vertices[0]; fCur.AlignAxis(2, (Vector3f)dv); Frame3f fStart = new Frame3f(fCur); // generate tube for (int ri = 0; ri < nRings; ++ri) { // propagate frame if (ri != 0) { Vector3d tan = CurveUtils.GetTangent(Vertices, ri); fCur.Origin = (Vector3f)Vertices[ri]; if (ri == 11) { dv = tan; } fCur.AlignAxis(2, (Vector3f)tan); } float uv_along = (float)ri / (float)(nRings - 1); // generate vertices int nStartR = ri * nRingSize; for (int j = 0; j < nRingSize; ++j) { float uv_around = (float)j / (float)(nRings); int k = nStartR + j; Vector2d pv = Polygon.Vertices[j % Slices]; Vector3d v = fCur.FromPlaneUV((Vector2f)pv, 2); vertices[k] = v; uv[k] = new Vector2f(uv_along, uv_around); Vector3f n = (Vector3f)(v - fCur.Origin).Normalized; normals[k] = n; } } // generate triangles int ti = 0; int nStop = (ClosedLoop) ? nRings : (nRings - 1); for (int ri = 0; ri < nStop; ++ri) { int r0 = ri * nRingSize; int r1 = r0 + nRingSize; if (ClosedLoop && ri == nStop - 1) { r1 = 0; } for (int k = 0; k < nRingSize - 1; ++k) { triangles.Set(ti++, r0 + k, r0 + k + 1, r1 + k + 1, Clockwise); triangles.Set(ti++, r0 + k, r1 + k + 1, r1 + k, Clockwise); } if (NoSharedVertices == false) // close disc if we went all the way { triangles.Set(ti++, r1 - 1, r0, r1, Clockwise); triangles.Set(ti++, r1 - 1, r1, r1 + nRingSize - 1, Clockwise); } } if (Capped && ClosedLoop == false) { // add endcap verts int nBottomC = nRings * nRingSize; vertices[nBottomC] = fStart.FromPlaneUV((Vector2f)CapCenter, 2); uv[nBottomC] = new Vector2f(0.5f, 0.5f); normals[nBottomC] = -fStart.Z; startCapCenterIndex = nBottomC; int nTopC = nBottomC + 1; vertices[nTopC] = fCur.FromPlaneUV((Vector2f)CapCenter, 2); uv[nTopC] = new Vector2f(0.5f, 0.5f); normals[nTopC] = fCur.Z; endCapCenterIndex = nTopC; if (NoSharedVertices) { // duplicate first loop and make a fan w/ bottom-center int nExistingB = 0; int nStartB = nTopC + 1; for (int k = 0; k < Slices; ++k) { vertices[nStartB + k] = vertices[nExistingB + k]; uv[nStartB + k] = (Vector2f)Polygon.Vertices[k].Normalized; normals[nStartB + k] = normals[nBottomC]; } append_disc(Slices, nBottomC, nStartB, true, Clockwise, ref ti); // duplicate second loop and make fan int nExistingT = nRingSize * (nRings - 1); int nStartT = nStartB + Slices; for (int k = 0; k < Slices; ++k) { vertices[nStartT + k] = vertices[nExistingT + k]; uv[nStartT + k] = (Vector2f)Polygon.Vertices[k].Normalized; normals[nStartT + k] = normals[nTopC]; } append_disc(Slices, nTopC, nStartT, true, !Clockwise, ref ti); } else { append_disc(Slices, nBottomC, 0, true, Clockwise, ref ti); append_disc(Slices, nTopC, nRingSize * (nRings - 1), true, !Clockwise, ref ti); } } return(this); }
/// <summary> /// Converts the provided float vector from g3 into the OpenTK variant. /// </summary> /// <param name="vector">The vector to convert from its current float variant. /// </param> /// <returns>An OpenTK vector to use in all calculations.</returns> public static Vector3 VectorConvert(g3.Vector3f vector) { return(new Vector3(vector.x, vector.y, vector.z)); }
public virtual bool Extrude() { MeshNormals normals = null; bool bHaveNormals = Mesh.HasVertexNormals; if (!bHaveNormals) { normals = new MeshNormals(Mesh); normals.Compute(); } InitialLoops = new MeshBoundaryLoops(Mesh); InitialTriangles = Mesh.TriangleIndices().ToArray(); InitialVertices = Mesh.VertexIndices().ToArray(); // duplicate triangles of mesh InitialToOffsetMapV = new IndexMap(Mesh.MaxVertexID, Mesh.MaxVertexID); OffsetGroupID = OffsetGroup.GetGroupID(Mesh); MeshEditor editor = new MeshEditor(Mesh); OffsetTriangles = editor.DuplicateTriangles(InitialTriangles, ref InitialToOffsetMapV, OffsetGroupID); // set vertices to new positions foreach (int vid in InitialVertices) { int newvid = InitialToOffsetMapV[vid]; if (!Mesh.IsVertex(newvid)) { continue; } Vector3d v = Mesh.GetVertex(vid); Vector3f n = (bHaveNormals) ? Mesh.GetVertexNormal(vid) : (Vector3f)normals.Normals[vid]; Vector3d newv = ExtrudedPositionF(v, n, vid); Mesh.SetVertex(newvid, newv); } // we need to reverse one side if (IsPositiveOffset) { editor.ReverseTriangles(InitialTriangles); } else { editor.ReverseTriangles(OffsetTriangles); } // stitch each loop NewLoops = new EdgeLoop[InitialLoops.Count]; StitchTriangles = new int[InitialLoops.Count][]; StitchGroupIDs = new int[InitialLoops.Count]; int li = 0; foreach (var loop in InitialLoops) { int[] loop2 = new int[loop.VertexCount]; for (int k = 0; k < loop2.Length; ++k) { loop2[k] = InitialToOffsetMapV[loop.Vertices[k]]; } StitchGroupIDs[li] = StitchGroups.GetGroupID(Mesh); if (IsPositiveOffset) { StitchTriangles[li] = editor.StitchLoop(loop2, loop.Vertices, StitchGroupIDs[li]); } else { StitchTriangles[li] = editor.StitchLoop(loop.Vertices, loop2, StitchGroupIDs[li]); } NewLoops[li] = EdgeLoop.FromVertices(Mesh, loop2); li++; } return(true); }
public override MeshGenerator Generate() { int nRings = Curve.Length; int nRingSize = (NoSharedVertices) ? Slices + 1 : Slices; int nCapVertices = (NoSharedVertices) ? Slices + 1 : 1; if (Capped == false) { nCapVertices = 0; } vertices = new VectorArray3d(nRingSize * nRings + 2 * nCapVertices); uv = new VectorArray2f(vertices.Count); normals = new VectorArray3f(vertices.Count); int nSpanTris = (nRings - 1) * (2 * Slices); int nCapTris = (Capped) ? 2 * Slices : 0; triangles = new IndexArray3i(nSpanTris + nCapTris); float fDelta = (float)((Math.PI * 2.0) / Slices); Frame3f f = Axis; // generate tube for (int ri = 0; ri < nRings; ++ri) { Vector3d v_along = Curve[ri]; Vector3f v_frame = f.ToFrameP((Vector3f)v_along); float uv_along = (float)ri / (float)(nRings - 1); // generate vertices int nStartR = ri * nRingSize; for (int j = 0; j < nRingSize; ++j) { float angle = (float)j * fDelta; // [TODO] this is not efficient...use Matrix3f? Vector3f v_rot = Quaternionf.AxisAngleR(Vector3f.AxisY, angle) * v_frame; Vector3d v_new = f.FromFrameP(v_rot); int k = nStartR + j; vertices[k] = v_new; float uv_around = (float)j / (float)(nRingSize); uv[k] = new Vector2f(uv_along, uv_around); // [TODO] proper normal Vector3f n = (Vector3f)(v_new - f.Origin).Normalized; normals[k] = n; } } // generate triangles int ti = 0; for (int ri = 0; ri < nRings - 1; ++ri) { int r0 = ri * nRingSize; int r1 = r0 + nRingSize; for (int k = 0; k < nRingSize - 1; ++k) { triangles.Set(ti++, r0 + k, r0 + k + 1, r1 + k + 1, Clockwise); triangles.Set(ti++, r0 + k, r1 + k + 1, r1 + k, Clockwise); } if (NoSharedVertices == false) // close disc if we went all the way { triangles.Set(ti++, r1 - 1, r0, r1, Clockwise); triangles.Set(ti++, r1 - 1, r1, r1 + nRingSize - 1, Clockwise); } } if (Capped) { // find avg start loop size Vector3d vAvgStart = Vector3d.Zero, vAvgEnd = Vector3d.Zero; for (int k = 0; k < Slices; ++k) { vAvgStart += vertices[k]; vAvgEnd += vertices[(nRings - 1) * nRingSize + k]; } vAvgStart /= (double)Slices; vAvgEnd /= (double)Slices; Frame3f fStart = f; fStart.Origin = (Vector3f)vAvgStart; Frame3f fEnd = f; fEnd.Origin = (Vector3f)vAvgEnd; // add endcap verts int nBottomC = nRings * nRingSize; vertices[nBottomC] = fStart.Origin; uv[nBottomC] = new Vector2f(0.5f, 0.5f); normals[nBottomC] = -fStart.Z; startCapCenterIndex = nBottomC; int nTopC = nBottomC + 1; vertices[nTopC] = fEnd.Origin; uv[nTopC] = new Vector2f(0.5f, 0.5f); normals[nTopC] = fEnd.Z; endCapCenterIndex = nTopC; if (NoSharedVertices) { // duplicate first loop and make a fan w/ bottom-center int nExistingB = 0; int nStartB = nTopC + 1; for (int k = 0; k < Slices; ++k) { vertices[nStartB + k] = vertices[nExistingB + k]; //uv[nStartB + k] = (Vector2f)Polygon.Vertices[k].Normalized; float angle = (float)k * fDelta; double cosa = Math.Cos(angle), sina = Math.Sin(angle); uv[nStartB + k] = new Vector2f(0.5f * (1.0f + cosa), 0.5f * (1 + sina)); normals[nStartB + k] = normals[nBottomC]; } append_disc(Slices, nBottomC, nStartB, true, Clockwise, ref ti); // duplicate second loop and make fan int nExistingT = nRingSize * (nRings - 1); int nStartT = nStartB + Slices; for (int k = 0; k < Slices; ++k) { vertices[nStartT + k] = vertices[nExistingT + k]; //uv[nStartT + k] = (Vector2f)Polygon.Vertices[k].Normalized; float angle = (float)k * fDelta; double cosa = Math.Cos(angle), sina = Math.Sin(angle); uv[nStartT + k] = new Vector2f(0.5f * (1.0f + cosa), 0.5f * (1 + sina)); normals[nStartT + k] = normals[nTopC]; } append_disc(Slices, nTopC, nStartT, true, !Clockwise, ref ti); } else { append_disc(Slices, nBottomC, 0, true, Clockwise, ref ti); append_disc(Slices, nTopC, nRingSize * (nRings - 1), true, !Clockwise, ref ti); } } return(this); }
public Vector3d(Vector3f copy) { x = copy.x; y = copy.y; z = copy.z; }
public static void AppendBox(DMesh3 mesh, Frame3f frame, Vector3f size, Colorf color) { MeshEditor editor = new MeshEditor(mesh); editor.AppendBox(frame, size, color); }
public void AppendBox(Frame3f frame, Vector3f size) { AppendBox(frame, size, Colorf.White); }
public Vector3f PointAt(Vector3f bary) { return(bary.x * V0 + bary.y * V1 + bary.z * V2); }
public Triangle3f(Vector3f v0, Vector3f v1, Vector3f v2) { V0 = v0; V1 = v1; V2 = v2; }