bool Delaunay3DWindow::CreateScene() { #if 1 // Randomly generated points in the cube [-1,1]^3. (0,0,0) is added to // ensure the hull contains the origin and the virtual trackball display // appears centered. std::mt19937 mte; std::uniform_real_distribution<float> rnd(-1.0f, 1.0f); mVertices.resize(128); for (auto& v : mVertices) { for (int j = 0; j < 3; ++j) { v[j] = rnd(mte); } } mVertices[0] = Vector3<float>::Zero(); #endif #if 0 // A cube with 3x3x3 points. mVertices.resize(27); for (int z = 0, i = 0; z < 3; ++z) { float fz = z - 1.0f; for (int y = 0; y < 3; ++y) { float fy = y - 1.0f; for (int x = 0; x < 3; ++x, ++i) { float fx = x - 1.0f; mVertices[i] = Vector3<float>(fx, fy, fz); } } } #endif #if 0 // Some pathological examples (needle-like configurations). //std::string filename = "data1.txt"; std::string filename = "data2.txt"; //std::string filename = "data3.txt"; std::string path = mEnvironment.GetPath(filename); if (path == "") { LogError("Cannot find file " + filename + "."); return false; } std::ifstream input(path); int numVertices; input >> numVertices; mVertices.resize(numVertices); for (int i = 0; i < numVertices; ++i) { for (int j = 0; j < 3; ++j) { input >> mVertices[i][j]; } } #endif Vector3<float> vmin, vmax; ComputeExtremes((int)mVertices.size(), &mVertices[0], vmin, vmax); for (int j = 0; j < 3; ++j) { mRandom[j] = std::uniform_real_distribution<float>(vmin[j], vmax[j]); } mDelaunay(static_cast<int>(mVertices.size()), &mVertices[0], 0.001f); mInfo.initialTetrahedron = -1; mInfo.finalTetrahedron = 0; mWireTetra.resize(mDelaunay.GetNumTetrahedra()); mSolidTetra.resize(mDelaunay.GetNumTetrahedra()); mScene = std::make_shared<Node>(); CreateSphere(); mVCEffect = std::make_shared<VertexColorEffect>(mProgramFactory); for (int j = 0; j < mDelaunay.GetNumTetrahedra(); ++j) { CreateTetra(j); } mCameraRig.Subscribe(mWireTetra[0]->worldTransform, mVCEffect->GetPVWMatrixConstant()); mTrackball.Attach(mScene); mTrackball.Update(); return true; }
void TriangulationCDTWindow::DrawTriangulation() { memset(mScreen->GetData(), 0xFF, mScreen->GetNumBytes()); Vector2<float> pmin, pmax; ComputeExtremes((int)mPoints.size(), &mPoints[0], pmin, pmax); int xmin = (int)floor(pmin[0]); int ymin = (int)floor(pmin[1]); int xmax = (int)ceil(pmax[0]); int ymax = (int)ceil(pmax[1]); int tStart = 0; for (int y = ymin; y <= ymax; ++y) { std::cout << "y = " << y << std::endl; for (int x = xmin; x <= xmax; ++x) { Vector2<float> test{ (float)x, (float)y }; int t = mPMesher->GetContainingTriangle(test, tStart); if (t >= 0) { if (mTriangulator->IsInside(t)) { mScreenTexels[x + mXSize * (mYSize - 1 - y)] = 0xFFFF8000; } else { mScreenTexels[x + mXSize * (mYSize - 1 - y)] = 0xFF0080FF; } tStart = t; } else { tStart = 0; } } } for (auto const& tri : mTriangulator->GetAllTriangles()) { int v0 = tri[0]; int v1 = tri[1]; int v2 = tri[2]; int x0 = (int)mPoints[v0][0]; int y0 = (int)mPoints[v0][1]; int x1 = (int)mPoints[v1][0]; int y1 = (int)mPoints[v1][1]; DrawLine(x0, y0, x1, y1); x0 = (int)mPoints[v1][0]; y0 = (int)mPoints[v1][1]; x1 = (int)mPoints[v2][0]; y1 = (int)mPoints[v2][1]; DrawLine(x0, y0, x1, y1); x0 = (int)mPoints[v2][0]; y0 = (int)mPoints[v2][1]; x1 = (int)mPoints[v0][0]; y1 = (int)mPoints[v0][1]; DrawLine(x0, y0, x1, y1); } }