void Delaunay::TrianglesToEdges(const TriangleSet& triangles, EdgeSet& edges) { for (cTriangleIterator iter = triangles.begin(); iter != triangles.end(); ++iter) { HandleEdge(iter->GetVertex(0), iter->GetVertex(1), edges); HandleEdge(iter->GetVertex(1), iter->GetVertex(2), edges); HandleEdge(iter->GetVertex(2), iter->GetVertex(0), edges); } }
void GuardianSystemDemo::InitSceneGraph() { for (int32_t i = 0; i < Scene::MAX_MODELS; ++i) { TriangleSet mesh; mesh.AddSolidColorBox(-0.035f, -0.035f, -0.035f, 0.035f, 0.035f, 0.035f, 0xFFFFFFFF); // Objects start 1 meter high mObjPosition[i] = XMVectorSet(0.0f, 1.0f, 0.0f, 1.0f); // Objects have random velocity mObjVelocity[i] = XMVectorSet(randVelocity(), randVelocity() * 0.5f, randVelocity(), 0); mObjVelocity[i] = XMVector3Normalize(mObjVelocity[i]) * 0.3f; Material* mat = new Material(new Texture(false, 256, 256, Texture::AUTO_FLOOR)); mDynamicScene.Add(new Model(&mesh, XMFLOAT3(0, 0, 0), XMFLOAT4(0, 0, 0, 1), mat)); } }
TriangleSet::TriangleSet(const TriangleSet &obj) : Node(obj.getNodeDescriptor()), m_compiled(obj.m_compiled), m_callList(obj.m_callList), m_material(obj.m_material), m_vertices(obj.m_vertices), m_normals(obj.m_normals), m_textureCoordinates(obj.m_textureCoordinates) {}
void MainLoop() { Layer[0] = new VRLayer(Session); // Create a trivial model to represent the left controller TriangleSet cube; cube.AddSolidColorBox(0.05f, -0.05f, 0.05f, -0.05f, 0.05f, -0.05f, 0xff404040); Model * controller = new Model(&cube, XMFLOAT3(0, 0, 0), XMFLOAT4(0, 0, 0, 1), new Material(new Texture(false, 256, 256, Texture::AUTO_CEILING))); // Main loop while (HandleMessages()) { // We don't allow yaw change for now, as this sample is too simple to cater for it. ActionFromInput(1.0f,false); ovrTrackingState hmdState = Layer[0]->GetEyePoses(); //Write position and orientation into controller model. controller->Pos = XMFLOAT3(XMVectorGetX(MainCam->Pos) + hmdState.HandPoses[ovrHand_Left].ThePose.Position.x, XMVectorGetY(MainCam->Pos) + hmdState.HandPoses[ovrHand_Left].ThePose.Position.y, XMVectorGetZ(MainCam->Pos) + hmdState.HandPoses[ovrHand_Left].ThePose.Position.z); controller->Rot = XMFLOAT4(hmdState.HandPoses[ovrHand_Left].ThePose.Orientation.x, hmdState.HandPoses[ovrHand_Left].ThePose.Orientation.y, hmdState.HandPoses[ovrHand_Left].ThePose.Orientation.z, hmdState.HandPoses[ovrHand_Left].ThePose.Orientation.w); //Button presses are modifying the colour of the controller model below ovrInputState inputState; ovr_GetInputState(Session, ovrControllerType_Touch, &inputState); for (int eye = 0; eye < 2; ++eye) { XMMATRIX viewProj = Layer[0]->RenderSceneToEyeBuffer(MainCam, RoomScene, eye); // Render the controller model controller->Render(&viewProj, 1, inputState.Buttons & ovrTouch_X ? 1.0f : 0.0f, inputState.Buttons & ovrTouch_Y ? 1.0f : 0.0f, 1, true); } Layer[0]->PrepareLayerHeader(); DistortAndPresent(1); } delete controller; }
Triangulation::~Triangulation() { TriangleSet outTriangles; triangles(&outTriangles); for(auto it = outTriangles.begin(); it != outTriangles.end(); it++) delete *it; mTlist->clear(); EdgeSet outEdges; edges(&outEdges); for(auto it = outEdges.begin(); it != outEdges.end(); it++) delete *it; VertexSet outVertices; vertices(&outVertices); for(auto it = outEdges.begin(); it != outEdges.end(); it++) delete *it; mV2VMap->clear(); }
int main(int argc, char* argv[]) { plbInit(&argc, &argv); global::directories().setOutputDir("./"); global::IOpolicy().activateParallelIO(false); string stlFileName, outFileName; T shiftX, shiftY, shiftZ; try { global::argv(1).read(stlFileName); global::argv(2).read(shiftX); global::argv(3).read(shiftY); global::argv(4).read(shiftZ); global::argv(5).read(outFileName); } catch (PlbIOException& exception) { pcout << "Wrong parameters; the syntax is: " << (std::string)global::argv(0) << " inputSTL.stl shiftX shiftY shiftZ outputSTL.stl" << std::endl; pcout << "If for example, you want your STL to be shifted by (0.1,0.1,0.1) you should write" << std::endl; pcout << (std::string)global::argv(0) << " inputSTL.stl 0.1 0.1 0.1 outputSTL.stl" << std::endl; exit(-1); } TriangleSet<T>* triangleSet = 0; try { triangleSet = new TriangleSet<T>(stlFileName, DBL); } catch (PlbIOException& exception) { pcout << "Error, could not read STL file " << stlFileName << ": " << exception.what() << std::endl; return -1; } triangleSet->translate(Array<T,3>(shiftX,shiftY,shiftZ)); triangleSet->writeBinarySTL(outFileName); return 0; }
void Delaunay::computeDelaunay(Mesh &mesh) { int size = (int)mesh.getVerticesSize(); if (size == 0) { return; } mesh.computeVerticesNormals(); m_preSize = mesh.m_curIndex; TriangleSet triSet; // 依次遍历每个点,寻找最近邻,进行三角化 for (; mesh.m_curIndex < size; mesh.m_curIndex++) { Vertex v = mesh.getVertex(mesh.m_curIndex); if (v.m_isInner) { mesh.pushTriBeginIndex((int)triSet.size()); continue; } Vec3d normal = v.m_normal; int id = 2; // 判断法向量哪个不为0,z->y->x if (normal[2] != 0) // z { id = 2; } else if (normal[1] != 0)// y { id = 1; } else if (normal[0] != 0)// x { id = 0; } else // 法向量为(0, 0, 0), { mesh.pushTriBeginIndex((int)triSet.size()); continue; } double minDistance = -1; int cnt = v.m_neighbors[0]; // 最近邻数目 double dists[k]; for (int j = 1; j < cnt + 1; j++) { Vec3d dv = mesh.getVertex(v.m_neighbors[j]).m_xyz - v.m_xyz; dists[j] = dv.ddot(dv); } minDistance = dists[1]; VertexVector vVector, tmpvVector; // 将最近邻点投射到该点的切平面上 for (int j = 1; j < cnt + 1; j++) { Vertex tmpv = mesh.getVertex(v.m_neighbors[j]); if (dists[j] < u * minDistance || // 去除非常接近的点 (tmpv.m_index < v.m_index && tmpv.m_index >= m_preSize) || // 去除已遍历过的点 tmpv.m_isInner) // 去除内点 { continue; } Vec3d vv = tmpv.m_xyz - v.m_xyz; double dist2 = dists[j] * 0.75f; // sqrt double alpha = vv.dot(normal); alpha = alpha * alpha; if (alpha > dist2) // 去除与法向量夹角小于30度或大于150度的点 { continue; } Vec3d proj = tmpv.m_xyz - alpha * normal; // 投射到切平面 tmpvVector.push_back(Vertex(proj, v.m_neighbors[j])); } if (tmpvVector.size() < 3) // 少于3个不能构成三角形 { mesh.pushTriBeginIndex((int)triSet.size()); continue; } // 将切平面转换为x-y平面进行三角形计算 vVector.push_back(Vertex(Vec3d(0, 0, 0), mesh.m_curIndex)); // 原点 Vec3d vx = tmpvVector[0].m_xyz - v.m_xyz; // x轴 vx = normalize(vx); for (int j = 0; j < tmpvVector.size(); j++) { Vec3d vv = tmpvVector[j].m_xyz - v.m_xyz; double x = vv.dot(vx); double y = vx.cross(vv)[id] / normal[id]; Vec3d proj(x, y, 0); vVector.push_back(Vertex(proj, tmpvVector[j].m_index)); } TriangleVector tVector; computeDelaunay(vVector, tVector); // cout << vVector.size() << " " << tVector.size() << endl; // drawTrianglesOnPlane(tVector); for (int j = 0; j < tVector.size(); j++) { Triangle t = tVector[j]; t.m_vertices[0] = mesh.getVertex(t.m_vertices[0].m_index); t.m_vertices[1] = mesh.getVertex(t.m_vertices[1].m_index); t.m_vertices[2] = mesh.getVertex(t.m_vertices[2].m_index); triSet.insert(t); } mesh.pushTriBeginIndex((int)triSet.size()); } for (TriangleSet::iterator iter = triSet.begin(); iter != triSet.end(); iter++) { mesh.m_triangles.push_back(*iter); } }
void Delaunay::Triangulate(const VertexSet& vertices, TriangleSet& output) { if (vertices.size() < 3) { return; } cVertexIterator iterVertex = vertices.begin(); double xMin = iterVertex->GetX(); double yMin = iterVertex->GetY(); double xMax = xMin; double yMax = yMin; ++iterVertex; for (; iterVertex != vertices.end(); ++iterVertex) { xMax = iterVertex->GetX(); double y = iterVertex->GetY(); if (y < yMin) { yMin = y; } if (y > yMax) { yMax = y; } } double dx = xMax - xMin; double dy = yMax - yMin; double ddx = dx * 0.01; double ddy = dy * 0.01; xMin -= ddx; xMax += ddx; dx += 2 * ddx; yMin -= ddy; yMax += ddy; dy += 2 * ddy; Vertex vSuper[3]; vSuper[0] = Vertex(xMin - dy * sqrt3 / 3.0, yMin); vSuper[1] = Vertex(xMax + dy * sqrt3 / 3.0, yMin); vSuper[2] = Vertex((xMin + xMax) * 0.5, yMax + dx * sqrt3 * 0.5); TriangleSet workset; workset.insert(Triangle(vSuper)); for (iterVertex = vertices.begin(); iterVertex != vertices.end(); ++iterVertex) { TriangleIsCompleted pred1(iterVertex, output, vSuper); TriangleSet::iterator iter = workset.begin(); while (iter != workset.end()) { if (pred1(*iter)) { iter = workset.erase(iter); } else { ++iter; } } EdgeSet edges; VertexIsInCircumstanceCircle pred2(iterVertex, edges); iter = workset.begin(); while (iter != workset.end()) { if (pred2(*iter)) { iter = workset.erase(iter); } else { ++iter; } } for (EdgeIterator edgeIter = edges.begin(); edgeIter != edges.end(); ++edgeIter) { workset.insert(Triangle(edgeIter->m_pv0, edgeIter->m_pv1, &(*iterVertex))); } } TriangleIterator where = output.begin(); TriangleHasVertex pred(vSuper); for (auto t : workset) { if (!pred(t)) { output.insert(output.begin(), t); } } }
int main(int argc, char* argv[]) { plbInit(&argc, &argv); global::directories().setOutputDir("./"); global::IOpolicy().activateParallelIO(false); if (argc != 9) { pcout << "Wrong parameters; the syntax is:" << std::endl << (std::string)global::argv(0) << "[FLT | DBL | LDBL | INF] inputSTL.stl cut-plane-point-x cut-plane-point-y cut-plane-point-z" << std::endl << "cut-plane-normal-x cut-plane-normal-y cut-plane-normal-z" << std::endl; exit(-1); } std::string precisionStr; std::string inStlFileName; Plane<T> cutPlane; try { global::argv(1).read(precisionStr); global::argv(2).read(inStlFileName); global::argv(3).read(cutPlane.point[0]); global::argv(4).read(cutPlane.point[1]); global::argv(5).read(cutPlane.point[2]); global::argv(6).read(cutPlane.normal[0]); global::argv(7).read(cutPlane.normal[1]); global::argv(8).read(cutPlane.normal[2]); } catch (PlbIOException& exception) { pcout << "Wrong parameters." << std::endl; exit(-1); } Precision precision; if (precisionStr == "FLT") { precision = FLT; } else if (precisionStr == "DBL") { precision = DBL; } else if (precisionStr == "LDBL") { precision = LDBL; } else if (precisionStr == "INF") { precision = INF; } else { pcout << "Wrong precision command-line argument." << std::endl; exit(-1); } TriangleSet<T>* set = 0; try { set = new TriangleSet<T>(inStlFileName, precision); } catch (PlbIOException& exception) { pcout << "ERROR, could not read STL file " << inStlFileName << ": " << exception.what() << std::endl; exit(-1); } // Cut the geometry in two parts. TriangleSet<T> normalNegativePart; int rv = 0; rv = set->cutWithPlane(cutPlane, normalNegativePart); if (rv != 1) { pcout << "Problem with the surface cutting." << std::endl; exit(1); } normalNegativePart.writeBinarySTL("normalNegativePart.stl"); TriangleSet<T> normalPositivePart; cutPlane.normal = -cutPlane.normal; rv = 0; rv = set->cutWithPlane(cutPlane, normalPositivePart); if (rv != 1) { pcout << "Problem with the surface cutting." << std::endl; exit(1); } normalPositivePart.writeBinarySTL("normalPositivePart.stl"); delete set; return 0; }
int main(int argc, char* argv[]) { plbInit(&argc, &argv); global::directories().setOutputDir("./"); plint n = 80; // Resolution (cylinder diameter). T radius = (T) n / 2.; // Cylinder radius. Array<T,3> center(0.0, 0.0, 0.0); // Cylinder center. T length = (T) (4 * n); // Cylinder length. plint nAxial = n / 2; // Two parameters needed for the creation of the triangularized cylinder surface. plint nCirc = 3 * n / 2; // Create a cylinder surface as a set of triangles. TriangleSet<T> cylinder; cylinder = constructCylinder<T>(center, radius, radius, length, nAxial, nCirc); cylinder.writeAsciiSTL("cylinder.stl"); // Define the cut plane by a point and a normal vector. Array<T,3> cutPlanePoint(length / 3.3, 0.0, 0.0); Array<T,3> cutPlaneNormal(-1.0, -0.1, -0.5); Plane<T> cutPlane; cutPlane.point = cutPlanePoint; cutPlane.normal = cutPlaneNormal; // Cut the cylinder in two parts. TriangleSet<T> rightCylinderPart; int rv = 0; rv = cylinder.cutWithPlane(cutPlane, rightCylinderPart); if (rv != 1) { pcout << "Problem with the surface cutting." << std::endl; exit(1); } rightCylinderPart.writeAsciiSTL("rightCylinderPart.stl"); TriangleSet<T> leftCylinderPart; cutPlane.normal = -cutPlane.normal; rv = 0; rv = cylinder.cutWithPlane(cutPlane, leftCylinderPart); if (rv != 1) { pcout << "Problem with the surface cutting." << std::endl; exit(1); } leftCylinderPart.writeAsciiSTL("leftCylinderPart.stl"); // Use a cuboid to cut the cylinder (correct usage). Array<T,3> lowerLeftCorner = cutPlanePoint - Array<T,3>(length, 5.0 * radius / 4.0, 5.0 * radius / 4.0); Array<T,3> upperRightCorner = cutPlanePoint + Array<T,3>(length / 4.0, 5.0 * radius / 4.0, 5.0 * radius / 4.0); Cuboid<T> cutCuboid; cutCuboid.lowerLeftCorner = lowerLeftCorner; cutCuboid.upperRightCorner = upperRightCorner; TriangleSet<T> newRightCylinderPart; cutPlane.normal = -cutPlane.normal; rv = 0; rv = cylinder.cutWithPlane(cutPlane, cutCuboid, newRightCylinderPart); if (rv != 1) { pcout << "Problem with the surface cutting." << std::endl; exit(1); } newRightCylinderPart.writeAsciiSTL("newRightCylinderPart.stl"); // Use a cuboid to cut the cylinder (wrong usage). upperRightCorner = cutPlanePoint + Array<T,3>(0.0, radius, radius); cutCuboid.upperRightCorner = upperRightCorner; TriangleSet<T> newBrokenRightCylinderPart; rv = 0; rv = cylinder.cutWithPlane(cutPlane, cutCuboid, newBrokenRightCylinderPart); if (rv != 1) { pcout << "Problem with the surface cutting." << std::endl; exit(1); } newBrokenRightCylinderPart.writeAsciiSTL("newBrokenRightCylinderPart.stl"); return 0; }