public void Precompute_SingleVectorBarycentric() { int N = DisplaceMesh.MaxTriangleID; BaryFaceDisplacements = new BaryDisplace[N]; //foreach ( int vid in DisplaceMesh.VertexIndices() ) { gParallel.ForEach <int>(DisplaceMesh.VertexIndices(), (vid) => { Vector3d pos = DisplaceMesh.GetVertex(vid); int tid = BaseSpatial.FindNearestTriangle(pos); DistPoint3Triangle3 dist = MeshQueries.TriangleDistance(BaseMesh, tid, pos); Vector3f dv = (Vector3f)(pos - dist.TriangleClosest); Frame3f triFrame = BaseMesh.GetTriFrame(tid); Vector3f relVec = triFrame.ToFrameV(dv); BaryFaceDisplacements[vid] = new BaryDisplace() { tID = tid, a = (float)dist.TriangleBaryCoords.x, b = (float)dist.TriangleBaryCoords.y, c = (float)dist.TriangleBaryCoords.z, dv = relVec }; }); }
protected override void update_vertices(FScene s) { if (Target.Timestamp == target_timestamp) { return; } target_timestamp = Target.Timestamp; DMesh3 Mesh = Target.Mesh; for (int i = 0; i < VertexCount; ++i) { SurfaceVertexRef r = SurfacePoints[i]; Vector3d vSum = Vector3d.Zero; Frame3f f = Mesh.GetTriFrame(r.tid); Index3i tv = Mesh.GetTriangle(r.tid); for (int j = 0; j < 3; ++j) { f.Origin = (Vector3f)Mesh.GetVertex(tv[j]); Vector3d v = f.FromFrameP(r.offsets[j]); vSum += v; } vSum /= 3; this[i] = SceneTransforms.ObjectToSceneP(Target, vSum); } }
public override void AppendVertex(Vector3d v) { base.AppendVertex(v); // map v to mesh v = SceneTransforms.SceneToObjectP(Target, v); // TODO encode vertices by normals ?? DMesh3 Mesh = Target.Mesh; DMeshAABBTree3 Spatial = Target.Spatial; SurfaceVertexRef r = new SurfaceVertexRef(); r.tid = Spatial.FindNearestTriangle(v); Frame3f f = Mesh.GetTriFrame(r.tid); Index3i tv = Mesh.GetTriangle(r.tid); for (int j = 0; j < 3; ++j) { f.Origin = (Vector3f)Mesh.GetVertex(tv[j]); Vector3d dv = f.ToFrameP(v); r.offsets[j] = dv; } SurfacePoints.Add(r); if (Curve.VertexCount != SurfacePoints.Count) { throw new Exception("SurfaceCurvePreview: counts are out of sync!!"); } }
public static void test_normals() { // check that frames are ok DMesh3 mesh = TestUtil.LoadTestInputMesh("bunny_solid.obj"); foreach (int tid in mesh.TriangleIndices()) { Vector3f n = (Vector3f)mesh.GetTriNormal(tid); for (int j = 0; j < 3; ++j) { Frame3f f = mesh.GetTriFrame(tid, j); if (Math.Abs(f.X.Dot(f.Y)) > MathUtil.ZeroTolerancef || Math.Abs(f.X.Dot(f.Z)) > MathUtil.ZeroTolerancef || Math.Abs(f.Y.Dot(f.Z)) > MathUtil.ZeroTolerancef) { throw new Exception("argh"); } Vector3f fn = f.Z; if (fn.Dot(n) < 0.99) { throw new Exception("shit"); } } } MeshNormals.QuickCompute(mesh); foreach (int vid in mesh.VertexIndices()) { Vector3f n = mesh.GetVertexNormal(vid); for (int j = 1; j <= 2; ++j) { Frame3f f = mesh.GetVertexFrame(vid, (j == 1) ? true : false); Vector3f fn = f.GetAxis(j); if (Math.Abs(f.X.Dot(f.Y)) > MathUtil.ZeroTolerancef || Math.Abs(f.X.Dot(f.Z)) > MathUtil.ZeroTolerancef || Math.Abs(f.Y.Dot(f.Z)) > MathUtil.ZeroTolerancef) { throw new Exception("argh"); } if (fn.Dot(n) < 0.99) { throw new Exception("shit2"); } } } }
public static void test_local_param() { //DMesh3 mesh = TestUtil.LoadTestInputMesh("plane_250v.obj"); //DMesh3 mesh = TestUtil.LoadTestInputMesh("hemisphere_nicemesh_3k.obj"); DMesh3 mesh = TestUtil.LoadTestInputMesh("bunny_open_base.obj"); mesh.EnableVertexUVs(Vector2f.Zero); DMeshAABBTree3 spatial = new DMeshAABBTree3(mesh); spatial.Build(); //int tid = spatial.FindNearestTriangle(Vector3d.Zero); //Frame3f seedF = new Frame3f(Vector3d.Zero, Vector3d.AxisY); int tid = 3137; Frame3f seedF = mesh.GetTriFrame(tid); Index3i seedNbrs = mesh.GetTriangle(tid); MeshLocalParam param = new MeshLocalParam(mesh.MaxVertexID, mesh.GetVertexf, mesh.GetVertexNormal, mesh.VtxVerticesItr); param.ComputeToMaxDistance(seedF, seedNbrs, float.MaxValue); float fR = param.MaxUVDistance; param.TransformUV(0.5f / fR, 0.5f * Vector2f.One); param.ApplyUVs((vid, uv) => { mesh.SetVertexUV(vid, uv); }); TestUtil.SetColorsFromScalarF(mesh, (vid) => { return(param.GetUV(vid).Distance(0.5f * Vector2f.One)); }, new Vector2f(0, 0.5f)); OBJWriter writer = new OBJWriter(); var s = new System.IO.StreamWriter(Program.TEST_OUTPUT_PATH + "mesh_local_param.obj", false); List <WriteMesh> wm = new List <WriteMesh>() { new WriteMesh(mesh) }; WriteOptions opt = new WriteOptions() { bCombineMeshes = false, bWriteGroups = false, bPerVertexColors = true, bPerVertexUVs = true, AsciiHeaderFunc = () => { return("mttllib checkerboard.mtl\r\nusemtl checkerboard\r\n"); } }; writer.Write(s, wm, opt); s.Close(); }
DMesh3 compute_partial_hole(Vector3d start, Vector3d end, double tol) { DMesh3 origMesh = MeshSource.GetDMeshUnsafe(); DMeshAABBTree3 origSpatial = MeshSource.GetSpatial() as DMeshAABBTree3; DMesh3 cutMesh = new DMesh3(origMesh); Polygon2d polygon = Polygon2d.MakeCircle(hole_size / 2, hole_subdivisions); Vector3f axis = (Vector3f)(start - end).Normalized; int start_tid = origSpatial.FindNearestTriangle(start); Frame3f start_frame = origMesh.GetTriFrame(start_tid); start_frame.Origin = (Vector3f)start; start_frame.AlignAxis(2, axis); int end_tid = origSpatial.FindNearestTriangle(end); //Frame3f end_frame = origMesh.GetTriFrame(end_tid); end_frame.Origin = (Vector3f)end; Frame3f end_frame = start_frame; end_frame.Origin = (Vector3f)end; // [TODO] we don't need to Simplify here...is more robust? MeshInsertProjectedPolygon start_insert = new MeshInsertProjectedPolygon(cutMesh, polygon, start_frame, start_tid); bool start_ok = start_insert.Insert(); if (start_ok == false) { throw new Exception("CutPolygonHoleOp.compute_partial_hole: start or end insertion failed!"); } EdgeLoop outLoop = start_insert.InsertedLoop; MeshExtrudeLoop extrude = new MeshExtrudeLoop(cutMesh, outLoop); extrude.PositionF = (v, n, vid) => { cutMesh.GetVertex(vid); return(end_frame.ProjectToPlane((Vector3f)v, 2)); }; extrude.Extrude(); SimpleHoleFiller filler = new SimpleHoleFiller(cutMesh, extrude.NewLoop); filler.Fill(); return(cutMesh); }
DMesh3 compute_through_hole(Vector3d start, Vector3d end, double tol) { DMesh3 origMesh = MeshSource.GetDMeshUnsafe(); DMeshAABBTree3 origSpatial = MeshSource.GetSpatial() as DMeshAABBTree3; DMesh3 cutMesh = new DMesh3(origMesh); Polygon2d polygon = Polygon2d.MakeCircle(hole_size / 2, hole_subdivisions); Vector3f axis = (Vector3f)(start - end).Normalized; int start_tid = origSpatial.FindNearestTriangle(start); Frame3f start_frame = origMesh.GetTriFrame(start_tid); start_frame.Origin = (Vector3f)start; start_frame.AlignAxis(2, axis); int end_tid = origSpatial.FindNearestTriangle(end); //Frame3f end_frame = origMesh.GetTriFrame(end_tid); end_frame.Origin = (Vector3f)end; Frame3f end_frame = start_frame; end_frame.Origin = (Vector3f)end; MeshInsertProjectedPolygon start_insert = new MeshInsertProjectedPolygon(cutMesh, polygon, start_frame, start_tid); bool start_ok = start_insert.Insert(); MeshInsertProjectedPolygon end_insert = new MeshInsertProjectedPolygon(cutMesh, polygon, end_frame, end_tid); bool end_ok = end_insert.Insert(); if (start_ok == false || end_ok == false) { throw new Exception("CutPolygonHoleOp.compute_through_hole: start or end insertion failed!"); } MeshEditor editor = new MeshEditor(cutMesh); EdgeLoop l0 = start_insert.InsertedLoop; EdgeLoop l1 = end_insert.InsertedLoop; l1.Reverse(); editor.StitchLoop(l0.Vertices, l1.Vertices); return(cutMesh); }