//-------------------------------------------------------------- public void modify() { if (mInputTriangleBuffer == null) { OGRE_EXCEPT("Exception::ERR_INVALID_STATE", "Input triangle buffer must be set", "__FUNCTION__"); } ; std_vector <TriangleBuffer.Vertex> newVertices = new std_vector <TriangleBuffer.Vertex>(); std_vector <TriangleBuffer.Vertex> originVertices = mInputTriangleBuffer.getVertices(); std_vector <int> originIndices = mInputTriangleBuffer.getIndices(); for (int i = 0; i < originIndices.size(); i += 3) { newVertices.push_back(originVertices[originIndices[i]]); newVertices.push_back(originVertices[originIndices[i + 1]]); newVertices.push_back(originVertices[originIndices[i + 2]]); } mInputTriangleBuffer.getVertices().clear(); mInputTriangleBuffer.getVertices().reserve(newVertices.size()); //for (List<TriangleBuffer.Vertex>.Enumerator it = newVertices.GetEnumerator(); it.MoveNext(); ++it) // mInputTriangleBuffer.getVertices().push_back(it.Current); foreach (var it in newVertices) { mInputTriangleBuffer.getVertices().push_back(it); } mInputTriangleBuffer.getIndices().clear(); mInputTriangleBuffer.getIndices().reserve(newVertices.size()); for (int i = 0; i < newVertices.size(); i++) { mInputTriangleBuffer.getIndices().push_back(i); } }
/// Copy constructor from an Ogre simplespline public CatmullRomSpline3(Mogre.SimpleSpline input) { mPoints.resize((int)input.NumPoints); for (ushort i = 0; i < input.NumPoints; i++) { mPoints.push_back(input.GetPoint(i)); } }
public void append(TriangleBuffer other) { rebaseOffset(); foreach (var it in other.mIndices) { mIndices.push_back(globalOffset + it); } foreach (var it in other.mVertices) { mVertices.push_back(it); } }
// //ORIGINAL LINE: List<std::pair<uint, uint> > getNoIntersectionParts(uint pathIndex) const /// <summary> /// 获取非交集 /// </summary> /// <param name="pathIndex"></param> /// <returns></returns> public std_vector <std_pair <uint, uint> > getNoIntersectionParts(uint pathIndex) { Path path = mPaths[(int)pathIndex]; std_vector <std_pair <uint, uint> > result = new std_vector <std_pair <uint, uint> >(); std_vector <int> intersections = new std_vector <int>(); //for (std.map<PathCoordinate, List<PathCoordinate>>.Enumerator it = mIntersectionsMap.begin(); it != mIntersectionsMap.end(); ++it) { foreach (var it in mIntersectionsMap) { if (it.Key.pathIndex == pathIndex) { intersections.push_back((int)it.Key.pointIndex); } } //std.sort(intersections.GetEnumerator(), intersections.end()); intersections.Sort((x, y) => { return(x - y);//正序排序(重写int比较器,|x|>|y|返回正数,|x|=|y|返回0,|x|<|y|返回负数) }); //Array.Sort(intersections.ToArray()); int begin = 0; //for (std::vector<int>::iterator it = intersections.begin(); it!= intersections.end(); ++it) //{ // if (*it-1>begin) // result.push_back(std::pair<unsigned int, unsigned int>(begin, *it-1)); // begin = *it+1; //} //if (path.getSegCount() > begin) // result.push_back(std::pair<unsigned int, unsigned int>(begin, path.getSegCount())); //for (List<int>.Enumerator it = intersections.GetEnumerator(); it.MoveNext(); ++it) foreach (var it in intersections) { if (it - 1 > begin) { result.push_back(new std_pair <uint, uint>((uint)begin, (uint)it - 1)); } begin = it + 1; } if (path.getSegCount() > begin) { result.push_back(new std_pair <uint, uint>((uint)begin, (uint)path.getSegCount())); } return(result); }
//----------------------------------------------------------------------- /// <summary> /// 查找交集 /// </summary> public void _calcIntersections() { mIntersectionsMap.Clear(); mIntersections.Clear(); //std::map<Ogre::Vector3, PathIntersection, Vector3Comparator> pointSet; std_map <Vector3, std_vector <PathCoordinate> > pointSet = new std_map <Vector3, std_vector <PathCoordinate> >(new Vector3Comparator()); // for (std::vector<Path>::iterator it = mPaths.begin(); it!= mPaths.end(); ++it) uint it_index = 0; foreach (var it in mPaths) { uint it_point_index = 0; //for (std::vector<Ogre::Vector3>::const_iterator it2 = it->getPoints().begin(); it2 != it->getPoints().end(); ++it2) foreach (var it2 in it._getPoints()) { //PathCoordinate pc(it-mPaths.begin(), it2-it->getPoints().begin()); PathCoordinate pc = new PathCoordinate(it_index, it_point_index); //if (pointSet.find(*it2)==pointSet.end()) if (!pointSet.ContainsKey(it2)) { std_vector <PathCoordinate> pi = new std_vector <PathCoordinate>(); pi.Add(pc); //pointSet[it2] = pi; pointSet.Add(it2, pi); } else { pointSet[it2].push_back(pc); } it_point_index++; } it_index++; } //for (std::map<Ogre::Vector3, PathIntersection, Vector3Comparator>::iterator it = pointSet.begin(); it != pointSet.end(); ++it) foreach (var it_ps in pointSet) { if (it_ps.Value.size() > 1) { foreach (var it2 in it_ps.Value) { //mIntersectionsMap[*it2] = it->second; if (mIntersectionsMap.ContainsKey(it2)) { mIntersectionsMap[it2] = it_ps.Value; } else { mIntersectionsMap.Add(it2, it_ps.Value); } } mIntersections.push_back(it_ps.Value); } } // }
public static void computeCatmullRomPoints(Vector3 P1, Vector3 P2, Vector3 P3, Vector3 P4, uint numSeg, ref std_vector <Vector3> pointList) { for (uint j = 0; j < numSeg; ++j) { float t = (float)j / (float)numSeg; float t2 = t * t; float t3 = t * t2; Vector3 P = 0.5f * ((-t3 + 2.0f * t2 - t) * P1 + (3.0f * t3 - 5.0f * t2 + 2.0f) * P2 + (-3.0f * t3 + 4.0f * t2 + t) * P3 + (t3 - t2) * P4); pointList.push_back(P); } }
//C++ TO C# CONVERTER TODO TASK: The original C++ template specifier was replaced with a C# generic specifier, which may not produce the same behavior: //ORIGINAL LINE: template <class T> //public static void computeKochanekBartelsPoints<T>(KochanekBartelsSplineControlPoint<T> P1, KochanekBartelsSplineControlPoint<T> P2, KochanekBartelsSplineControlPoint<T> P3, KochanekBartelsSplineControlPoint<T> P4, uint numSeg, ref List<T> pointList) { // Vector2 m0 = (1 - P2.tension) * (1 + P2.bias) * (1 + P2.continuity) / 2.0f * (P2.position - P1.position) + (1 - P2.tension) * (1 - P2.bias) * (1 - P2.continuity) / 2.0f * (P3.position - P2.position); // Vector2 m1 = (1 - P3.tension) * (1 + P3.bias) * (1 - P3.continuity) / 2.0f * (P3.position - P2.position) + (1 - P3.tension) * (1 - P3.bias) * (1 + P3.continuity) / 2.0f * (P4.position - P3.position); // for (uint j = 0; j < numSeg; ++j) { // float t = (float)j / (float)numSeg; // float t2 = t * t; // float t3 = t2 * t; // T P = (2 * t3 - 3 * t2 + 1) * P2.position + (t3 - 2 * t2 + t) * m0 + (-2 * t3 + 3 * t2) * P3.position + (t3 - t2) * m1; // pointList.Add(P); // } //} public static void computeKochanekBartelsPoints(KochanekBartelsSplineControlPoint <Vector2> P1, KochanekBartelsSplineControlPoint <Vector2> P2, KochanekBartelsSplineControlPoint <Vector2> P3, KochanekBartelsSplineControlPoint <Vector2> P4, uint numSeg, ref std_vector <Vector2> pointList) { Vector2 m0 = (1 - P2.tension) * (1 + P2.bias) * (1 + P2.continuity) / 2.0f * (P2.position - P1.position) + (1 - P2.tension) * (1 - P2.bias) * (1 - P2.continuity) / 2.0f * (P3.position - P2.position); Vector2 m1 = (1 - P3.tension) * (1 + P3.bias) * (1 - P3.continuity) / 2.0f * (P3.position - P2.position) + (1 - P3.tension) * (1 - P3.bias) * (1 + P3.continuity) / 2.0f * (P4.position - P3.position); for (uint j = 0; j < numSeg; ++j) { float t = (float)j / (float)numSeg; float t2 = t * t; float t3 = t2 * t; Vector2 P = (2 * t3 - 3 * t2 + 1) * P2.position + (t3 - 2 * t2 + t) * m0 + (-2 * t3 + 3 * t2) * P3.position + (t3 - t2) * m1; pointList.push_back(P); } }
/// Adds a control point public BezierCurve2 addPoint(Vector2 pt) { mPoints.push_back(pt); return(this); }
//std_vector<std::string> split(const std::string& str, const std::string& delimiters, bool removeEmpty = true); std_vector<string> split(string str, string delimiters, bool removeEmpty) { std_vector<string> tokens = new std_vector<string>(); //std::string::size_type delimPos = 0, tokenPos = 0, pos = 0; //int delimPos = 0, tokenPos = 0, pos = 0; //if (str.empty()) return tokens; if (string.IsNullOrEmpty(str)) return tokens; string[] strsplits = str.Split(delimiters.ToCharArray()); foreach (var v in strsplits) { if (removeEmpty) { if (!string.IsNullOrEmpty(v)) { tokens.push_back(v); } } else { tokens.push_back(v); } } //while (true) //{ // delimPos = str.find_first_of(delimiters, pos); // tokenPos = str.find_first_not_of(delimiters, pos); // if (std::string::npos != delimPos) // { // if (std::string::npos != tokenPos) // { // if (tokenPos < delimPos) // tokens.push_back(str.substr(pos,delimPos-pos)); // else // { // if (!removeEmpty) tokens.push_back(""); // } // } // else // { // if (!removeEmpty) tokens.push_back(""); // } // pos = delimPos+1; // } // else // { // if (std::string::npos != tokenPos) // tokens.push_back(str.substr(pos)); // else // { // if (!removeEmpty) tokens.push_back(""); // } // break; // } //} return tokens; }
/// Adds a control point public CubicHermiteSpline2 addPoint(Vector2 p, Vector2 before, Vector2 after) { mPoints.push_back(new CubicHermiteSplineControlPoint <Vector2>(p, before, after)); return(this); }
/// Adds a control point public RoundedCornerSpline2 addPoint(Vector2 p) { mPoints.push_back(p); return(this); }
/// Adds a control point public CatmullRomSpline2 addPoint(Vector2 pt) { mPoints.push_back(pt); return(this); }
/// Adds a control point public KochanekBartelsSpline2 addPoint(float x, float y) { mPoints.push_back(new KochanekBartelsSplineControlPoint <Vector2>(new Vector2(x, y))); return(this); }
//-------------------------------------------------------------- public void modify() { if (mInputTriangleBuffer == null) OGRE_EXCEPT("Exception::ERR_INVALID_STATE", "Input triangle buffer must be set", "__FUNCTION__"); ; std_vector<TriangleBuffer.Vertex> newVertices = new std_vector<TriangleBuffer.Vertex>(); std_vector<TriangleBuffer.Vertex> originVertices = mInputTriangleBuffer.getVertices(); std_vector<int> originIndices = mInputTriangleBuffer.getIndices(); for (int i = 0; i < originIndices.size(); i += 3) { newVertices.push_back(originVertices[originIndices[i]]); newVertices.push_back(originVertices[originIndices[i + 1]]); newVertices.push_back(originVertices[originIndices[i + 2]]); } mInputTriangleBuffer.getVertices().clear(); mInputTriangleBuffer.getVertices().reserve(newVertices.size()); //for (List<TriangleBuffer.Vertex>.Enumerator it = newVertices.GetEnumerator(); it.MoveNext(); ++it) // mInputTriangleBuffer.getVertices().push_back(it.Current); foreach (var it in newVertices) { mInputTriangleBuffer.getVertices().push_back(it); } mInputTriangleBuffer.getIndices().clear(); mInputTriangleBuffer.getIndices().reserve(newVertices.size()); for (int i = 0; i < newVertices.size(); i++) mInputTriangleBuffer.getIndices().push_back(i); }
/// Adds a control point public CubicHermiteSpline3 addPoint(Vector3 p, Vector3 before, Vector3 after) { mPoints.push_back(new ControlPoint(p, before, after)); return(this); }
//----------------------------------------------------------------------- public static void _retriangulate(ref TriangleBuffer newMesh, TriangleBuffer inputMesh, std_vector <Intersect> intersectionList, bool first) { std_vector <TriangleBuffer.Vertex> vec = inputMesh.getVertices(); std_vector <int> ind = inputMesh.getIndices(); // Triangulate // Group intersections by triangle indice std_map <int, std_vector <Segment3D> > meshIntersects = new std_map <int, std_vector <Segment3D> >(); //for (List<Intersect>.Enumerator it = intersectionList.GetEnumerator(); it.MoveNext(); ++it) foreach (var it in intersectionList) { int it2_find; if (first) { it2_find = meshIntersects.find(it.mTri1); } else { it2_find = meshIntersects.find(it.mTri2); } if (it2_find != -1) { std_pair <int, std_vector <Segment3D> > it2 = meshIntersects.get((uint)it2_find); it2.second.push_back(it.mSeg); } else { std_vector <Segment3D> vec2 = new std_vector <Segment3D>(); vec2.push_back(it.mSeg); if (first) { meshIntersects[it.mTri1] = vec2; } else { meshIntersects[it.mTri2] = vec2; } } } // Build a new TriangleBuffer holding non-intersected triangles and retriangulated-intersected triangles //for (List<TriangleBuffer.Vertex>.Enumerator it = vec.GetEnumerator(); it.MoveNext(); ++it) foreach (var it in vec) { newMesh.vertex(it); } //for (int i = 0; i < (int)ind.Count / 3; i++) // if (meshIntersects.find(i) == meshIntersects.end()) // newMesh.triangle(ind[i * 3], ind[i * 3 + 1], ind[i * 3 + 2]); for (int i = 0; i < (int)ind.size() / 3; i++) { if (meshIntersects.find(i) == -1) { newMesh.triangle(ind[i * 3], ind[i * 3 + 1], ind[i * 3 + 2]); } } int numNonIntersected1 = newMesh.getIndices().size(); //for (std.map<int, List<Segment3D> >.Enumerator it = meshIntersects.begin(); it.MoveNext(); ++it) foreach (var it in meshIntersects) { std_vector <Segment3D> segments = it.Value; int triIndex = it.Key; Vector3 v1 = vec[ind[triIndex * 3]].mPosition; Vector3 v2 = vec[ind[triIndex * 3 + 1]].mPosition; Vector3 v3 = vec[ind[triIndex * 3 + 2]].mPosition; Vector3 triNormal = ((v2 - v1).CrossProduct(v3 - v1)).NormalisedCopy; Vector3 xAxis = triNormal.Perpendicular; Vector3 yAxis = triNormal.CrossProduct(xAxis); Vector3 planeOrigin = vec[ind[triIndex * 3]].mPosition; // Project intersection segments onto triangle plane std_vector <Segment2D> segments2 = new std_vector <Segment2D>(); //for (List<Segment3D>.Enumerator it2 = segments.GetEnumerator(); it2.MoveNext(); it2++) // segments2.Add(projectOnAxis(it2.Current, planeOrigin, xAxis, yAxis)); foreach (var it2 in segments) { segments2.push_back(projectOnAxis(it2, planeOrigin, xAxis, yAxis)); } //for (List<Segment2D>.Enumerator it2 = segments2.GetEnumerator(); it2.MoveNext();) int it2_c = segments2.Count; for (int j = it2_c - 1; j >= 0; j--) { Segment2D it2 = segments2[j]; if ((it2.mA - it2.mB).SquaredLength < 1e-5) { //C++ TO C# CONVERTER TODO TASK: There is no direct equivalent to the STL vector 'erase' method in C#: //it2 = segments2.erase(it2); segments2.RemoveAt(j); } //else } // Triangulate Triangulator t = new Triangulator(); //Triangle2D[[]] tri = new Triangle2D[ind[triIndex * 3]](projectOnAxis(vec.mPosition, planeOrigin, xAxis, yAxis), projectOnAxis(vec[ind[triIndex * 3 + 1]].mPosition, planeOrigin, xAxis, yAxis), projectOnAxis(vec[ind[triIndex * 3 + 2]].mPosition, planeOrigin, xAxis, yAxis)); Triangle2D tri = new Triangle2D(projectOnAxis(vec[ind[triIndex * 3]].mPosition, planeOrigin, xAxis, yAxis), projectOnAxis(vec[ind[triIndex * 3 + 1]].mPosition, planeOrigin, xAxis, yAxis), projectOnAxis(vec[ind[triIndex * 3 + 2]].mPosition, planeOrigin, xAxis, yAxis)); std_vector <Vector2> outPointList = new std_vector <Vector2>();//PointList outPointList; std_vector <int> outIndice = new std_vector <int>(); t.setManualSuperTriangle(tri).setRemoveOutside(false).setSegmentListToTriangulate(ref segments2).triangulate(outIndice, outPointList); // Deproject and add to triangleBuffer newMesh.rebaseOffset(); //for (List<int>.Enumerator it = outIndice.GetEnumerator(); it.MoveNext(); ++it) // newMesh.index(it.Current); foreach (var oindex in outIndice) { newMesh.index(oindex); } float x1 = tri.mPoints[0].x; float y1 = tri.mPoints[0].y; Vector2 uv1 = vec[ind[triIndex * 3]].mUV; float x2 = tri.mPoints[1].x; float y2 = tri.mPoints[1].y; Vector2 uv2 = vec[ind[triIndex * 3 + 1]].mUV; float x3 = tri.mPoints[2].x; float y3 = tri.mPoints[2].y; Vector2 uv3 = vec[ind[triIndex * 3 + 2]].mUV; float DET = x1 * y2 - x2 * y1 + x2 * y3 - x3 * y2 + x3 * y1 - x1 * y3; Vector2 A = ((y2 - y3) * uv1 + (y3 - y1) * uv2 + (y1 - y2) * uv3) / DET; Vector2 B = ((x3 - x2) * uv1 + (x1 - x3) * uv2 + (x2 - x1) * uv3) / DET; Vector2 C = ((x2 * y3 - x3 * y2) * uv1 + (x3 * y1 - x1 * y3) * uv2 + (x1 * y2 - x2 * y1) * uv3) / DET; //for (List<Vector2>.Enumerator it = outPointList.GetEnumerator(); it.MoveNext(); ++it) foreach (var it2 in outPointList) { Vector2 uv = A * it2.x + B * it2.y + C; newMesh.position(deprojectOnAxis(it2, planeOrigin, xAxis, yAxis)); newMesh.normal(triNormal); newMesh.textureCoord(uv); } } }
// * // * Builds the mesh into the given TriangleBuffer // * @param buffer The TriangleBuffer on where to append the mesh. // // //ORIGINAL LINE: void addToTriangleBuffer(TriangleBuffer& buffer) const public override void addToTriangleBuffer(ref TriangleBuffer buffer) { std_vector <Vector3> vertices = new std_vector <Vector3>(); int offset = 0; /// Step 1 : Generate icosahedron float phi = 0.5f * (1.0f + Math.Sqrt(5.0f)); float invnorm = 1f / Math.Sqrt(phi * phi + 1f); vertices.push_back(invnorm * new Vector3(-1f, phi, 0f)); //0 vertices.push_back(invnorm * new Vector3(1f, phi, 0f)); //1 vertices.push_back(invnorm * new Vector3(0f, 1f, -phi)); //2 vertices.push_back(invnorm * new Vector3(0f, 1f, phi)); //3 vertices.push_back(invnorm * new Vector3(-phi, 0f, -1f)); //4 vertices.push_back(invnorm * new Vector3(-phi, 0f, 1f)); //5 vertices.push_back(invnorm * new Vector3(phi, 0f, -1f)); //6 vertices.push_back(invnorm * new Vector3(phi, 0f, 1f)); //7 vertices.push_back(invnorm * new Vector3(0f, -1f, -phi)); //8 vertices.push_back(invnorm * new Vector3(0f, -1f, phi)); //9 vertices.push_back(invnorm * new Vector3(-1f, -phi, 0f)); //10 vertices.push_back(invnorm * new Vector3(1f, -phi, 0f)); //11 int[] firstFaces = { 0, 1, 2, 0, 3, 1, 0, 4, 5, 1, 7, 6, 1, 6, 2, 1, 3, 7, 0, 2, 4, 0, 5, 3, 2, 6, 8, 2, 8, 4, 3, 5, 9, 3, 9, 7, 11, 6, 7, 10, 5, 4, 10, 4, 8, 10, 9, 5, 11, 8, 6, 11, 7, 9, 10, 8, 11, 10, 11, 9 }; //C++ TO C# CONVERTER WARNING: This 'sizeof' ratio was replaced with a direct reference to the array length: //ORIGINAL LINE: std::vector<int> faces(firstFaces, firstFaces + sizeof(firstFaces)/sizeof(*firstFaces)); // 定义一个容纳100个int型数据的容器,初值赋为0 //vector<int> vecMyHouse(100,0); std_vector <int> faces = new std_vector <int>(firstFaces);//(firstFaces, firstFaces + firstFaces.Length); int size = 60; /// Step 2 : tessellate for (ushort iteration = 0; iteration < mNumIterations; iteration++) { size *= 4; std_vector <int> newFaces = new std_vector <int>(); newFaces.Clear(); //newFaces.resize(size); for (int i = 0; i < size / 12; i++) { int i1 = faces[i * 3]; int i2 = faces[i * 3 + 1]; int i3 = faces[i * 3 + 2]; int i12 = vertices.Count; int i23 = i12 + 1; int i13 = i12 + 2; Vector3 v1 = vertices[i1]; Vector3 v2 = vertices[i2]; Vector3 v3 = vertices[i3]; //make 1 vertice at the center of each edge and project it onto the sphere vertices.push_back((v1 + v2).NormalisedCopy); vertices.push_back((v2 + v3).NormalisedCopy); vertices.push_back((v1 + v3).NormalisedCopy); //now recreate indices newFaces.push_back(i1); newFaces.push_back(i12); newFaces.push_back(i13); newFaces.push_back(i2); newFaces.push_back(i23); newFaces.push_back(i12); newFaces.push_back(i3); newFaces.push_back(i13); newFaces.push_back(i23); newFaces.push_back(i12); newFaces.push_back(i23); newFaces.push_back(i13); } //faces.swap(newFaces); faces = newFaces; } /// Step 3 : generate texcoords std_vector <Vector2> texCoords = new std_vector <Vector2>(); for (ushort i = 0; i < vertices.size(); i++) { Vector3 vec = vertices[i]; float u = 0f; float v = 0f; float r0 = sqrtf(vec.x * vec.x + vec.z * vec.z); float alpha = 0f; alpha = atan2f(vec.z, vec.x); u = alpha / Math.TWO_PI + .5f; v = atan2f(vec.y, r0) / Math.PI + .5f; texCoords.push_back(new Vector2(u, v)); } /// Step 4 : fix texcoords // find vertices to split std_vector <int> indexToSplit = new std_vector <int>(); for (int i = 0; i < faces.size() / 3; i++) { Vector2 t0 = texCoords[faces[i * 3 + 0]]; Vector2 t1 = texCoords[faces[i * 3 + 1]]; Vector2 t2 = texCoords[faces[i * 3 + 2]]; if (Math.Abs(t2.x - t0.x) > 0.5) { if (t0.x < 0.5) { indexToSplit.push_back(faces[i * 3]); } else { indexToSplit.push_back(faces[i * 3 + 2]); } } if (Math.Abs(t1.x - t0.x) > 0.5) { if (t0.x < 0.5) { indexToSplit.push_back(faces[i * 3]); } else { indexToSplit.push_back(faces[i * 3 + 1]); } } if (Math.Abs(t2.x - t1.x) > 0.5) { if (t1.x < 0.5) { indexToSplit.push_back(faces[i * 3 + 1]); } else { indexToSplit.push_back(faces[i * 3 + 2]); } } } //split vertices for (ushort i = 0; i < indexToSplit.size(); i++) { int index = indexToSplit[i]; //duplicate vertex Vector3 v = vertices[index]; Vector2 t = texCoords[index] + Vector2.UNIT_X; vertices.push_back(v); texCoords.push_back(t); int newIndex = vertices.size() - 1; //reassign indices for (ushort j = 0; j < faces.size(); j++) { if (faces[j] == index) { int index1 = faces[(j + 1) % 3 + (j / 3) * 3]; int index2 = faces[(j + 2) % 3 + (j / 3) * 3]; if ((texCoords[index1].x > 0.5f) || (texCoords[index2].x > 0.5f)) { faces[j] = newIndex; } } } } /// Step 5 : realize buffer.rebaseOffset(); buffer.estimateVertexCount((uint)vertices.size()); buffer.estimateIndexCount((uint)size); for (ushort i = 0; i < vertices.size(); i++) { addPoint(ref buffer, mRadius * vertices[i], vertices[i], new Vector2(texCoords[i].x, texCoords[i].y)); } for (ushort i = 0; i < size; i++) { buffer.index(offset + faces[i]); } offset += vertices.size(); }
public MultiPath addPath(Path path) { mPaths.push_back(path); return(this); }
//* Adds a point to the path, as a Vector3 public Path addPoint(Vector3 pt) { mPoints.push_back(pt); return(this); }
public void buildFromSegmentSoup(std_vector <Segment3D> segList, ref std_vector <Path> @out) { //typedef std::multimap<Vector3, Vector3, Vector3Comparator> Vec3MultiMap; //Vec3MultiMap segs; std_multimap <Vector3, Vector3> segs = new std_multimap <Vector3, Vector3>(new Vector3Comparator()); // for (std::vector<Segment3D>::const_iterator it = segList.begin(); it != segList.end(); ++it) foreach (var it in segList) { //segs.insert(std::pair<Vector3, Vector3 > (it->mA, it->mB)); //segs.insert(std::pair<Vector3, Vector3 > (it->mB, it->mA)); segs.insert(it.mA, it.mB); segs.insert(it.mB, it.mA); } while (!segs.empty()) { Vector3 headFirst = segs.get(0).first; //segs.begin()->first; Vector3 headSecond = segs.get(0).second[0]; //segs.begin()->second; Path p = new Path(); p.addPoint(headFirst).addPoint(headSecond); //Vec3MultiMap::iterator firstSeg = segs.begin(); int firstSeg_pos = segs.begin(); Vector3 firstSeg = segs.get(0).first; //std::pair<Vec3MultiMap::iterator, Vec3MultiMap::iterator> correspondants2 = segs.equal_range(headSecond); std_pair <std_pair <Vector3, List <Vector3> >, std_pair <Vector3, List <Vector3> > > correspondants2 = segs.equal_range(headSecond); //for (Vec3MultiMap::iterator it = correspondants2.first; it != correspondants2.second;) for (int i = correspondants2.first.second.Count - 1; i >= 0; i--) { // Vec3MultiMap::iterator removeIt = it++; Vector3 removeIt = correspondants2.first.second[i]; //if ((removeIt->second - firstSeg->first).squaredLength() < 1e-8) if ((removeIt - firstSeg).SquaredLength < 1e-8) { segs.erase(removeIt); } } segs.erase(firstSeg); bool foundSomething = true; while (!segs.empty() && foundSomething) { foundSomething = false; //Vec3MultiMap::iterator next = segs.find(headSecond); int next_pos = segs.find(headSecond); //if (next != segs.end()) if (next_pos != -1) { std_pair <Vector3, List <Vector3> > next = segs.get((uint)next_pos); foundSomething = true; headSecond = next.second[0]; p.addPoint(headSecond); //std::pair<Vec3MultiMap::iterator, Vec3MultiMap::iterator> correspondants = segs.equal_range(headSecond); std_pair <std_pair <Vector3, List <Vector3> >, std_pair <Vector3, List <Vector3> > > correspondants = segs.equal_range(headSecond); //for (Vec3MultiMap::iterator it = correspondants.first; it != correspondants.second;) for (int i = correspondants.first.second.Count - 1; i >= 0; i--) { //Vec3MultiMap::iterator removeIt = it++; Vector3 removeIt = correspondants.first.second[i]; //if ((removeIt->second - next->first).squaredLength() < 1e-8) if ((removeIt - next.first).SquaredLength < 1e-8) { segs.erase(removeIt); } } //segs.erase(next); segs.erase(next.first); } //Vec3MultiMap::iterator previous = segs.find(headFirst); int previous_pos = segs.find(headFirst); //if (previous != segs.end()) if (previous_pos != -1) { std_pair <Vector3, List <Vector3> > previous = segs.get((uint)previous_pos); foundSomething = true; //p.insertPoint(0, previous.second); p.insertPoint(0, previous.second[0]);//??? headFirst = previous.second[0]; //std::pair<Vec3MultiMap::iterator, Vec3MultiMap::iterator> correspondants = segs.equal_range(headFirst); std_pair <std_pair <Vector3, List <Vector3> >, std_pair <Vector3, List <Vector3> > > correspondants = segs.equal_range(headFirst); //for (Vec3MultiMap::iterator it = correspondants.first; it != correspondants.second;) for (int i = correspondants.first.second.Count - 1; i >= 0; i--) { //Vec3MultiMap::iterator removeIt = it++; Vector3 removeIt = correspondants.first.second[i]; //if ((removeIt->second - previous->first).squaredLength() < 1e-8) if ((removeIt - previous.first).SquaredLength < 1e-8) { segs.erase(removeIt); } } //segs.erase(previous); segs.erase(previous.first); } } if ((p.getPoint(0) - p.getPoint(p.getSegCount() + 1)).SquaredLength < 1e-6) { p.getPointsReference().pop_back(); p.close(); } @out.push_back(p); } }
// SvgLoaderPath(std::vector<std::string> p, unsigned int ns); public SvgLoaderPath(std_vector <string> p, uint ns) { parts = p; mNumSeg = ns; px = 0.0f; py = 0.0f; index = 0; char lastCmd = (char)0; while (index < p.Count) { try { char newCmd = parts[index][0]; bool next = true; if (lastCmd != newCmd && newCmd != '.' && newCmd != '-' && (newCmd < '0' || newCmd > '9') && curve.size() > 3 && ((lastCmd == 'c' || lastCmd == 'C') && (newCmd == 's' || newCmd == 'S') || (lastCmd == 'q' || lastCmd == 'Q') && (newCmd == 't' || newCmd == 'T'))) { // finish curve finishCurve(lastCmd); } switch (newCmd) { case 'l': parseLineTo(true, next); break; case 'L': parseLineTo(false, next); break; case 'm': parseMoveTo(true, next); newCmd = 'l'; break; case 'M': parseMoveTo(false, next); newCmd = 'L'; break; case 'h': parseHLineTo(true, next); break; case 'H': parseHLineTo(false, next); break; case 'v': parseVLineTo(true, next); break; case 'V': parseVLineTo(false, next); break; case 'c': curve.push_back(point); parseCurveCTo(true, next); break; case 'C': curve.push_back(point); parseCurveCTo(false, next); break; case 's': parseCurveSTo(true, next); break; case 'S': parseCurveSTo(false, next); break; case 'q': curve.push_back(point); parseCurveQTo(true, next); break; case 'Q': curve.push_back(point); parseCurveQTo(false, next); break; case 't': parseCurveTTo(true, next); break; case 'T': parseCurveTTo(false, next); break; case 'a': parseArcTo(true, next); break; case 'A': parseArcTo(false, next); break; case 'z': case 'Z': shape.close(); index++; break; default: newCmd = lastCmd; next = false; switch (lastCmd) { case 'l': parseLineTo(true, next); break; case 'L': parseLineTo(false, next); break; case 'm': parseMoveTo(true, next); break; case 'M': parseMoveTo(false, next); break; case 'h': parseHLineTo(true, next); break; case 'H': parseHLineTo(false, next); break; case 'v': parseVLineTo(true, next); break; case 'V': parseVLineTo(false, next); break; case 'c': parseCurveCTo(true, next); break; case 'C': parseCurveCTo(false, next); break; case 's': parseCurveSTo(true, next); break; case 'S': parseCurveSTo(false, next); break; case 'q': parseCurveQTo(true, next); break; case 'Q': parseCurveQTo(false, next); break; case 't': parseCurveTTo(true, next); break; case 'T': parseCurveTTo(false, next); break; case 'a': parseArcTo(true, next); break; case 'A': parseArcTo(false, next); break; default: break; } break; } lastCmd = newCmd; } catch { } } if (curve.size() > 0) { finishCurve(lastCmd); } }
//std_vector<std::string> split(const std::string& str, const std::string& delimiters, bool removeEmpty = true); std_vector <string> split(string str, string delimiters, bool removeEmpty) { std_vector <string> tokens = new std_vector <string>(); //std::string::size_type delimPos = 0, tokenPos = 0, pos = 0; //int delimPos = 0, tokenPos = 0, pos = 0; //if (str.empty()) return tokens; if (string.IsNullOrEmpty(str)) { return(tokens); } string[] strsplits = str.Split(delimiters.ToCharArray()); foreach (var v in strsplits) { if (removeEmpty) { if (!string.IsNullOrEmpty(v)) { tokens.push_back(v); } } else { tokens.push_back(v); } } //while (true) //{ // delimPos = str.find_first_of(delimiters, pos); // tokenPos = str.find_first_not_of(delimiters, pos); // if (std::string::npos != delimPos) // { // if (std::string::npos != tokenPos) // { // if (tokenPos < delimPos) // tokens.push_back(str.substr(pos,delimPos-pos)); // else // { // if (!removeEmpty) tokens.push_back(""); // } // } // else // { // if (!removeEmpty) tokens.push_back(""); // } // pos = delimPos+1; // } // else // { // if (std::string::npos != tokenPos) // tokens.push_back(str.substr(pos)); // else // { // if (!removeEmpty) tokens.push_back(""); // } // break; // } //} return(tokens); }
//----------------------------------------------------------------------- //typedef std::vector<PathCoordinate> PathIntersection; public static void _extrudeIntersectionImpl(ref TriangleBuffer buffer, std_vector <MultiPath.PathCoordinate> intersection, MultiPath multiPath, Shape shape, Track shapeTextureTrack) { Vector3 intersectionLocation = multiPath.getPath((int)intersection[0].pathIndex).getPoint((int)intersection[0].pointIndex); Quaternion firstOrientation = Utils._computeQuaternion(multiPath.getPath((int)intersection[0].pathIndex).getDirectionBefore((int)intersection[0].pointIndex)); Vector3 refX = firstOrientation * Vector3.UNIT_X; Vector3 refZ = firstOrientation * Vector3.UNIT_Z; std_vector <Vector2> v2s = new std_vector <Vector2>(); std_vector <MultiPath.PathCoordinate> coords = new std_vector <MultiPath.PathCoordinate>(); std_vector <float> direction = new std_vector <float>(); for (int i = 0; i < intersection.size(); ++i) { Path path = multiPath.getPath((int)intersection[i].pathIndex); int pointIndex = (int)intersection[i].pointIndex; if (pointIndex > 0 || path.isClosed()) { Vector3 vb = path.getDirectionBefore(pointIndex); Vector2 vb2 = new Vector2(vb.DotProduct(refX), vb.DotProduct(refZ)); v2s.push_back(vb2); coords.push_back(intersection[i]); direction.push_back(1); } if (pointIndex < path.getSegCount() || path.isClosed()) { Vector3 va = -path.getDirectionAfter(pointIndex); Vector2 va2 = new Vector2(va.DotProduct(refX), va.DotProduct(refZ)); v2s.push_back(va2); coords.push_back(intersection[i]); direction.push_back(-1); } } std_map <Radian, int> angles = new std_map <Radian, int>(); for (int i = 1; i < v2s.Count; ++i) { //angles[Utils.angleTo(v2s[0], v2s[i])] = i; angles.insert(Utils.angleTo(v2s[0], v2s[i]), i); } std_vector <int> orderedIndices = new std_vector <int>(); orderedIndices.push_back(0); //for (std_map<Radian, int>.Enumerator it = angles.begin(); it != angles.end(); ++it) foreach (var it in angles) { orderedIndices.push_back(it.Value); } for (int i = 0; i < orderedIndices.size(); ++i) { int idx = orderedIndices[i]; int idxBefore = orderedIndices[Utils.modulo(i - 1, orderedIndices.Count)]; int idxAfter = orderedIndices[Utils.modulo(i + 1, orderedIndices.Count)]; Radian angleBefore = (Utils.angleBetween(v2s[idx], v2s[idxBefore]) - (Radian)Math.PI) / 2; Radian angleAfter = ((Radian)Math.PI - Utils.angleBetween(v2s[idx], v2s[idxAfter])) / 2; int pointIndex = (int)((int)coords[idx].pointIndex - direction[idx]); Path path = multiPath.getPath((int)coords[idx].pathIndex); Quaternion qStd = Utils._computeQuaternion(path.getAvgDirection(pointIndex) * direction[idx]); float lineicPos = 0f; float uTexCoord = path.getLengthAtPoint(pointIndex) / path.getTotalLength(); // Shape making the joint with "standard extrusion" _extrudeShape(ref buffer, shape, path.getPoint(pointIndex), qStd, qStd, 1.0f, 1.0f, 1.0f, shape.getTotalLength(), uTexCoord, true, shapeTextureTrack); // Modified shape at the intersection Quaternion q = new Quaternion(); if (direction[idx] > 0f) { q = Utils._computeQuaternion(path.getDirectionBefore((int)coords[idx].pointIndex)); } else { q = Utils._computeQuaternion(-path.getDirectionAfter((int)coords[idx].pointIndex)); } Quaternion qLeft = q * new Quaternion(angleBefore, Vector3.UNIT_Y); Quaternion qRight = q * new Quaternion(angleAfter, Vector3.UNIT_Y); float scaleLeft = 1.0f / Math.Abs(Math.Cos(angleBefore)); float scaleRight = 1.0f / Math.Abs(Math.Cos(angleAfter)); uTexCoord = path.getLengthAtPoint((int)coords[idx].pointIndex) / path.getTotalLength(); _extrudeShape(ref buffer, shape, path.getPoint((int)coords[idx].pointIndex), qLeft, qRight, 1.0f, scaleLeft, scaleRight, shape.getTotalLength(), uTexCoord, false, shapeTextureTrack); } }
// //ORIGINAL LINE: List<std::pair<uint, uint> > getNoIntersectionParts(uint pathIndex) const /// <summary> /// 获取非交集 /// </summary> /// <param name="pathIndex"></param> /// <returns></returns> public std_vector<std_pair<uint, uint>> getNoIntersectionParts(uint pathIndex) { Path path = mPaths[(int)pathIndex]; std_vector<std_pair<uint, uint>> result = new std_vector<std_pair<uint, uint>>(); std_vector<int> intersections = new std_vector<int>(); //for (std.map<PathCoordinate, List<PathCoordinate>>.Enumerator it = mIntersectionsMap.begin(); it != mIntersectionsMap.end(); ++it) { foreach (var it in mIntersectionsMap) { if (it.Key.pathIndex == pathIndex) { intersections.push_back((int)it.Key.pointIndex); } } //std.sort(intersections.GetEnumerator(), intersections.end()); intersections.Sort((x, y) => { return x - y;//正序排序(重写int比较器,|x|>|y|返回正数,|x|=|y|返回0,|x|<|y|返回负数) }); //Array.Sort(intersections.ToArray()); int begin = 0; //for (std::vector<int>::iterator it = intersections.begin(); it!= intersections.end(); ++it) //{ // if (*it-1>begin) // result.push_back(std::pair<unsigned int, unsigned int>(begin, *it-1)); // begin = *it+1; //} //if (path.getSegCount() > begin) // result.push_back(std::pair<unsigned int, unsigned int>(begin, path.getSegCount())); //for (List<int>.Enumerator it = intersections.GetEnumerator(); it.MoveNext(); ++it) foreach (var it in intersections) { if (it - 1 > begin) result.push_back(new std_pair<uint, uint>((uint)begin, (uint)it - 1)); begin = it + 1; } if (path.getSegCount() > begin) result.push_back(new std_pair<uint, uint>((uint)begin, (uint)path.getSegCount())); return result; }
void _addConstraints(ref DelaunayTriangleBuffer tbuffer, PointList pl, std_vector <int> segmentListIndices) { std_vector <DelaunaySegment> segList = new std_vector <DelaunaySegment>(); //Utils::log("a co"); //for (DelaunayTriangleBuffer::iterator it = tbuffer.begin(); it!=tbuffer.end();it++) // Utils::log(it->debugDescription()); // First, list all the segments that are not already in one of the delaunay triangles //for (std::vector<int>::const_iterator it2 = segmentListIndices.begin(); it2 != segmentListIndices.end(); it2++) for (int i = 0; i < segmentListIndices.Count; i++) { //int i1 = *it2; int i1 = segmentListIndices[i]; //it2++; i++; //int i2 = *it2; int i2 = segmentListIndices[i]; bool isAlreadyIn = false; //for (DelaunayTriangleBuffer::iterator it = tbuffer.begin(); it!=tbuffer.end(); ++it) foreach (var it in tbuffer) { if (it.containsSegment(i1, i2)) { isAlreadyIn = true; break; } } // only do something for segments not already in DT if (!isAlreadyIn) { segList.push_back(new DelaunaySegment(i1, i2)); } } // Re-Triangulate according to the new segments //for (std::vector<DelaunaySegment>::iterator itSeg=segList.begin(); itSeg!=segList.end(); itSeg++) for (int ii = segList.Count - 1; ii >= 0; ii--) { DelaunaySegment itSeg = segList[ii]; //Utils::log("itseg " + StringConverter::toString(itSeg->i1) + "," + StringConverter::toString(itSeg->i2) + " " + StringConverter::toString(pl[itSeg->i1]) + "," + StringConverter::toString(pl[itSeg->i2])); // Remove all triangles intersecting the segment and keep a list of outside edges std_set <DelaunaySegment> segments = new std_set <DelaunaySegment>(); Segment2D seg1 = new Segment2D(pl[itSeg.i1], pl[itSeg.i2]); //for (DelaunayTriangleBuffer::iterator itTri = tbuffer.begin(); itTri!=tbuffer.end(); ) for (int jj = tbuffer.Count - 1; jj >= 0; jj--) { Triangle itTri = tbuffer.getElement(jj).Value; bool isTriangleIntersected = false; bool isDegenerate = false; int degenIndex; for (int i = 0; i < 3; i++) { //Early out if 2 points are in fact the same if (itTri.i[i] == itSeg.i1 || itTri.i[i] == itSeg.i2 || itTri.i[(i + 1) % 3] == itSeg.i1 || itTri.i[(i + 1) % 3] == itSeg.i2) { if (itTri.isDegenerate()) { if (itTri.i[i] == itSeg.i1 || itTri.i[(i + 1) % 3] == itSeg.i1) { degenIndex = itSeg.i1; } else if (itTri.i[i] == itSeg.i2 || itTri.i[(i + 1) % 3] == itSeg.i2) { degenIndex = itSeg.i2; } isTriangleIntersected = true; isDegenerate = true; } else { continue; } } Segment2D seg2 = new Segment2D(itTri.p(i), itTri.p((i + 1) % 3)); if (seg1.intersects(seg2)) { isTriangleIntersected = true; break; } } if (isTriangleIntersected) { //if (isDegenerate) //Utils::log("degen " + itTri->debugDescription()); for (int k = 0; k < 3; k++) { DelaunaySegment d1 = new DelaunaySegment(itTri.i[k], itTri.i[(k + 1) % 3]); if (segments.find(d1) != segments.end()) { segments.erase(d1); } else if (segments.find(d1.inverse()) != segments.end()) { segments.erase(d1.inverse()); } else { segments.insert(d1); } } //itTri=tbuffer.erase(itTri); tbuffer.erase(jj); } //else // itTri++; } // Divide the list of points (coming from remaining segments) in 2 groups : "above" and "below" std_vector <int> pointsAbove = new std_vector <int>(); std_vector <int> pointsBelow = new std_vector <int>(); int pt = itSeg.i1; bool isAbove = true; while (segments.size() > 0) { //find next point //for (std::set<DelaunaySegment>::iterator it = segments.begin(); it!=segments.end(); ++it) DelaunaySegment[] segments_all = segments.get_allocator(); for (int i = 0; i < segments_all.Length; ++i) { DelaunaySegment it = segments_all[i];//segments.find(i,true); if (it.i1 == pt || it.i2 == pt) { //Utils::log("next " + StringConverter::toString(pt)); if (it.i1 == pt) { pt = it.i2; } else { pt = it.i1; } segments.erase(it); if (pt == itSeg.i2) { isAbove = false; } else if (pt != itSeg.i1) { if (isAbove) { pointsAbove.push_back(pt); } else { pointsBelow.push_back(pt); } } break; } } } // Recursively triangulate both polygons _recursiveTriangulatePolygon(itSeg, pointsAbove, tbuffer, pl); _recursiveTriangulatePolygon(itSeg.inverse(), pointsBelow, tbuffer, pl); } // Clean up segments outside of multishape if (mRemoveOutside) { if (mMultiShapeToTriangulate != null && mMultiShapeToTriangulate.isClosed()) { //for (DelaunayTriangleBuffer::iterator it = tbuffer.begin(); it!=tbuffer.end();) for (int i = tbuffer.Count - 1; i >= 0; i--) { Triangle it = tbuffer.getElement(i).Value; bool isTriangleOut = !mMultiShapeToTriangulate.isPointInside(it.getMidPoint()); if (isTriangleOut) { //it = tbuffer.erase(it); tbuffer.erase(i); } //else // ++it; } } else if (mShapeToTriangulate != null && mShapeToTriangulate.isClosed()) { //for (DelaunayTriangleBuffer::iterator it = tbuffer.begin(); it!=tbuffer.end();) for (int i = tbuffer.Count - 1; i >= 0; i--) { Triangle it = tbuffer.getElement(i).Value; bool isTriangleOut = !mShapeToTriangulate.isPointInside(it.getMidPoint()); if (isTriangleOut) { //it = tbuffer.erase(it); tbuffer.erase(i); } //else // ++it; } } } }
//----------------------------------------------------------------------- // //ORIGINAL LINE: void addToTriangleBuffer(TriangleBuffer& buffer) const public override void addToTriangleBuffer(ref TriangleBuffer buffer) { std_vector <TriangleBuffer.Vertex> vec1 = mMesh1.getVertices(); std_vector <int> ind1 = mMesh1.getIndices(); std_vector <TriangleBuffer.Vertex> vec2 = mMesh2.getVertices(); std_vector <int> ind2 = mMesh2.getIndices(); Segment3D intersectionResult = new Segment3D(); std_vector <Intersect> intersectionList = new std_vector <Intersect>(); // Find all intersections between mMesh1 and mMesh2 int idx1 = 0; //for (std::vector<int>::const_iterator it = ind1.begin(); it != ind1.end(); idx1++) for (int i = 0; i < ind1.Count; i += 3, idx1++) { int it = ind1[i]; //Triangle3D t1(vec1[*it++].mPosition, vec1[*it++].mPosition, vec1[*it++].mPosition); Triangle3D t1 = new Triangle3D(vec1[it].mPosition, vec1[it + 1].mPosition, vec1[it + 2].mPosition); int idx2 = 0; //for (std::vector<int>::const_iterator it2 = ind2.begin(); it2 != ind2.end(); idx2++) for (int j = 0; j < ind2.Count; j += 3, idx2++) { int it2 = ind2[j]; //Triangle3D t2(vec2[*it2++].mPosition, vec2[*it2++].mPosition, vec2[*it2++].mPosition); Triangle3D t2 = new Triangle3D(vec2[it2].mPosition, vec2[it2 + 1].mPosition, vec2[it2 + 2].mPosition); if (t1.findIntersect(t2, ref intersectionResult)) { Intersect intersect = new Intersect(intersectionResult, idx1, idx2); intersectionList.push_back(intersect); } } } // Remove all intersection segments too small to be relevant //for (std::vector<Intersect>::iterator it = intersectionList.begin(); it != intersectionList.end();) // if ((it.mSeg.mB - it.mSeg.mA).squaredLength() < 1e-8) // it = intersectionList.erase(it); // else // ++it; for (int i = intersectionList.Count - 1; i >= 0; i--) { Intersect it = intersectionList[i]; if ((it.mSeg.mB - it.mSeg.mA).SquaredLength < 1e-8) { intersectionList.erase((uint)i); } } // Retriangulate TriangleBuffer newMesh1 = new TriangleBuffer(); TriangleBuffer newMesh2 = new TriangleBuffer(); GlobalMembersProceduralBoolean._retriangulate(ref newMesh1, mMesh1, intersectionList, true); GlobalMembersProceduralBoolean._retriangulate(ref newMesh2, mMesh2, intersectionList, false); //buffer.append(newMesh1); //buffer.append(newMesh2); //return; // Trace contours std_vector <Path> contours = new std_vector <Path>(); std_vector <Segment3D> segmentSoup = new std_vector <Segment3D>(); //for (std::vector<Intersect>::iterator it = intersectionList.begin(); it != intersectionList.end(); ++it) foreach (var it in intersectionList) { segmentSoup.push_back(it.mSeg); } new Path().buildFromSegmentSoup(segmentSoup, ref contours); // Build a lookup from segment to triangle TriLookup triLookup1 = new std_multimap <Segment3D, int>(new Seg3Comparator()), triLookup2 = new std_multimap <Segment3D, int>(new Seg3Comparator()); GlobalMembersProceduralBoolean._buildTriLookup(ref triLookup1, newMesh1); GlobalMembersProceduralBoolean._buildTriLookup(ref triLookup2, newMesh2); std_set <Segment3D> limits = new std_set <Segment3D>(new Seg3Comparator()); //for (std::vector<Segment3D>::iterator it = segmentSoup.begin(); it != segmentSoup.end(); ++it) foreach (var it in segmentSoup) { limits.insert(it.orderedCopy()); } // Build resulting mesh //for (std::vector<Path>::iterator it = contours.begin(); it != contours.end(); ++it) foreach (var it in contours) { // Find 2 seed triangles for each contour Segment3D firstSeg = new Segment3D(it.getPoint(0), it.getPoint(1)); //std_pair<TriLookup::iterator, TriLookup::iterator> it2mesh1 = triLookup1.equal_range(firstSeg.orderedCopy()); //std_pair<TriLookup::iterator, TriLookup::iterator> it2mesh2 = triLookup2.equal_range(firstSeg.orderedCopy()); std_pair <std_pair <Segment3D, List <int> >, std_pair <Segment3D, List <int> > > it2mesh1 = triLookup1.equal_range(firstSeg.orderedCopy()); std_pair <std_pair <Segment3D, List <int> >, std_pair <Segment3D, List <int> > > it2mesh2 = triLookup2.equal_range(firstSeg.orderedCopy()); int mesh1seed1 = 0, mesh1seed2 = 0, mesh2seed1 = 0, mesh2seed2 = 0; //if (it2mesh1.first != triLookup1.end() && it2mesh2.first != triLookup2.end()) if (it2mesh1.first != null && it2mesh2.first != null) { // check which of seed1 and seed2 must be included (it can be 0, 1 or both) //mesh1seed1 = it2mesh1.first.second; //mesh1seed2 = (--it2mesh1.second).second; //mesh2seed1 = it2mesh2.first.second; //mesh2seed2 = (--it2mesh2.second).second; mesh1seed1 = it2mesh1.first.second[0]; mesh1seed2 = it2mesh1.first.second[it2mesh1.first.second.Count - 1]; //(--it2mesh1.second).second[0]; mesh2seed1 = it2mesh2.first.second[0]; mesh2seed2 = it2mesh2.first.second[it2mesh2.first.second.Count - 1]; //(--it2mesh2.second).second[0]; if (mesh1seed1 == mesh1seed2) { mesh1seed2 = -1; } if (mesh2seed1 == mesh2seed2) { mesh2seed2 = -1; } Vector3 vMesh1 = new Vector3(0f, 0f, 0f), nMesh1 = new Vector3(0f, 0f, 0f), vMesh2 = new Vector3(0f, 0f, 0f), nMesh2 = new Vector3(0f, 0f, 0f); for (int i = 0; i < 3; i++) { Vector3 pos = newMesh1.getVertices()[newMesh1.getIndices()[mesh1seed1 * 3 + i]].mPosition; if ((pos - firstSeg.mA).SquaredLength > 1e-6 && (pos - firstSeg.mB).SquaredLength > 1e-6) { vMesh1 = pos; nMesh1 = newMesh1.getVertices()[newMesh1.getIndices()[mesh1seed1 * 3 + i]].mNormal; break; } } for (int i = 0; i < 3; i++) { Vector3 pos = newMesh2.getVertices()[newMesh2.getIndices()[mesh2seed1 * 3 + i]].mPosition; if ((pos - firstSeg.mA).SquaredLength > 1e-6 && (pos - firstSeg.mB).SquaredLength > 1e-6) { vMesh2 = pos; nMesh2 = newMesh2.getVertices()[newMesh2.getIndices()[mesh2seed1 * 3 + i]].mNormal; break; } } bool M2S1InsideM1 = (nMesh1.DotProduct(vMesh2 - firstSeg.mA) < 0f); bool M1S1InsideM2 = (nMesh2.DotProduct(vMesh1 - firstSeg.mA) < 0f); GlobalMembersProceduralBoolean._removeFromTriLookup(mesh1seed1, ref triLookup1); GlobalMembersProceduralBoolean._removeFromTriLookup(mesh2seed1, ref triLookup2); GlobalMembersProceduralBoolean._removeFromTriLookup(mesh1seed2, ref triLookup1); GlobalMembersProceduralBoolean._removeFromTriLookup(mesh2seed2, ref triLookup2); // Recursively add all neighbours of these triangles // Stop when a contour is touched switch (mBooleanOperation) { case BooleanOperation.BT_UNION: if (M1S1InsideM2) { GlobalMembersProceduralBoolean._recursiveAddNeighbour(ref buffer, newMesh1, mesh1seed2, ref triLookup1, limits, false); } else { GlobalMembersProceduralBoolean._recursiveAddNeighbour(ref buffer, newMesh1, mesh1seed1, ref triLookup1, limits, false); } if (M2S1InsideM1) { GlobalMembersProceduralBoolean._recursiveAddNeighbour(ref buffer, newMesh2, mesh2seed2, ref triLookup2, limits, false); } else { GlobalMembersProceduralBoolean._recursiveAddNeighbour(ref buffer, newMesh2, mesh2seed1, ref triLookup2, limits, false); } break; case BooleanOperation.BT_INTERSECTION: if (M1S1InsideM2) { GlobalMembersProceduralBoolean._recursiveAddNeighbour(ref buffer, newMesh1, mesh1seed1, ref triLookup1, limits, false); } else { GlobalMembersProceduralBoolean._recursiveAddNeighbour(ref buffer, newMesh1, mesh1seed2, ref triLookup1, limits, false); } if (M2S1InsideM1) { GlobalMembersProceduralBoolean._recursiveAddNeighbour(ref buffer, newMesh2, mesh2seed1, ref triLookup2, limits, false); } else { GlobalMembersProceduralBoolean._recursiveAddNeighbour(ref buffer, newMesh2, mesh2seed2, ref triLookup2, limits, false); } break; case BooleanOperation.BT_DIFFERENCE: if (M1S1InsideM2) { GlobalMembersProceduralBoolean._recursiveAddNeighbour(ref buffer, newMesh1, mesh1seed2, ref triLookup1, limits, false); } else { GlobalMembersProceduralBoolean._recursiveAddNeighbour(ref buffer, newMesh1, mesh1seed1, ref triLookup1, limits, false); } if (M2S1InsideM1) { GlobalMembersProceduralBoolean._recursiveAddNeighbour(ref buffer, newMesh2, mesh2seed1, ref triLookup2, limits, true); } else { GlobalMembersProceduralBoolean._recursiveAddNeighbour(ref buffer, newMesh2, mesh2seed2, ref triLookup2, limits, true); } break; } } } }
public void buildFromSegmentSoup(std_vector<Segment3D> segList, ref std_vector<Path> @out) { //typedef std::multimap<Vector3, Vector3, Vector3Comparator> Vec3MultiMap; //Vec3MultiMap segs; std_multimap<Vector3,Vector3>segs=new std_multimap<Vector3,Vector3>(new Vector3Comparator()); // for (std::vector<Segment3D>::const_iterator it = segList.begin(); it != segList.end(); ++it) foreach(var it in segList) { //segs.insert(std::pair<Vector3, Vector3 > (it->mA, it->mB)); //segs.insert(std::pair<Vector3, Vector3 > (it->mB, it->mA)); segs.insert(it.mA,it.mB); segs.insert(it.mB,it.mA); } while (!segs.empty()) { Vector3 headFirst = segs.get(0).first;//segs.begin()->first; Vector3 headSecond = segs.get(0).second[0];//segs.begin()->second; Path p=new Path(); p.addPoint(headFirst).addPoint(headSecond); //Vec3MultiMap::iterator firstSeg = segs.begin(); int firstSeg_pos=segs.begin(); Vector3 firstSeg=segs.get(0).first; //std::pair<Vec3MultiMap::iterator, Vec3MultiMap::iterator> correspondants2 = segs.equal_range(headSecond); std_pair<std_pair<Vector3,List<Vector3>>,std_pair<Vector3,List<Vector3>>> correspondants2 = segs.equal_range(headSecond); //for (Vec3MultiMap::iterator it = correspondants2.first; it != correspondants2.second;) for(int i=correspondants2.first.second.Count-1;i>=0;i--) { // Vec3MultiMap::iterator removeIt = it++; Vector3 removeIt=correspondants2.first.second[i]; //if ((removeIt->second - firstSeg->first).squaredLength() < 1e-8) if((removeIt-firstSeg).SquaredLength<1e-8) segs.erase(removeIt); } segs.erase(firstSeg); bool foundSomething = true; while (!segs.empty() && foundSomething) { foundSomething = false; //Vec3MultiMap::iterator next = segs.find(headSecond); int next_pos = segs.find(headSecond); //if (next != segs.end()) if(next_pos!=-1) { std_pair<Vector3,List<Vector3>>next=segs.get((uint)next_pos); foundSomething = true; headSecond = next.second[0]; p.addPoint(headSecond); //std::pair<Vec3MultiMap::iterator, Vec3MultiMap::iterator> correspondants = segs.equal_range(headSecond); std_pair<std_pair<Vector3,List<Vector3>>,std_pair<Vector3,List<Vector3>>>correspondants = segs.equal_range(headSecond); //for (Vec3MultiMap::iterator it = correspondants.first; it != correspondants.second;) for (int i = correspondants.first.second.Count - 1; i >= 0;i-- ) { //Vec3MultiMap::iterator removeIt = it++; Vector3 removeIt = correspondants.first.second[i]; //if ((removeIt->second - next->first).squaredLength() < 1e-8) if ((removeIt - next.first).SquaredLength < 1e-8) segs.erase(removeIt); } //segs.erase(next); segs.erase(next.first); } //Vec3MultiMap::iterator previous = segs.find(headFirst); int previous_pos=segs.find(headFirst); //if (previous != segs.end()) if(previous_pos!=-1) { std_pair<Vector3, List<Vector3>> previous = segs.get((uint)previous_pos); foundSomething = true; //p.insertPoint(0, previous.second); p.insertPoint(0, previous.second[0]);//??? headFirst = previous.second[0]; //std::pair<Vec3MultiMap::iterator, Vec3MultiMap::iterator> correspondants = segs.equal_range(headFirst); std_pair<std_pair<Vector3,List<Vector3>>,std_pair<Vector3,List<Vector3>>>correspondants = segs.equal_range(headFirst); //for (Vec3MultiMap::iterator it = correspondants.first; it != correspondants.second;) for(int i=correspondants.first.second.Count-1;i>=0;i--) { //Vec3MultiMap::iterator removeIt = it++; Vector3 removeIt=correspondants.first.second[i]; //if ((removeIt->second - previous->first).squaredLength() < 1e-8) if((removeIt-previous.first).SquaredLength<1e-8) segs.erase(removeIt); } //segs.erase(previous); segs.erase(previous.first); } } if ((p.getPoint(0)-p.getPoint(p.getSegCount() + 1)).SquaredLength < 1e-6) { p.getPointsReference().pop_back(); p.close(); } @out.push_back(p); } }
// * // * Executes the Constrained Delaunay Triangulation algorithm // * @param output A vector of index where is outputed the resulting triangle indexes // * @param outputVertices A vector of vertices where is outputed the resulting triangle vertices // * @exception Ogre::InvalidStateException Either shape or multishape or segment list must be defined // //void triangulate(ref List<int>& output, ref List<Vector2>& outputVertices) const; public void triangulate(std_vector <int> output, PointList outputVertices) { if (mShapeToTriangulate == null && mMultiShapeToTriangulate == null && mSegmentListToTriangulate == null) { throw new NullReferenceException("Ogre::Exception::ERR_INVALID_STATE," + "Either shape or multishape or segment list must be defined!" + ", Procedural::Triangulator::triangulate(std::vector<int>&, PointList&)"); } //Ogre::Timer mTimer; //Mogre.Timer mTimer = new Timer(); //mTimer.Reset(); DelaunayTriangleBuffer dtb = new std_list <Triangle>(); // Do the Delaunay triangulation std_vector <int> segmentListIndices = new std_vector <int>(); if (mShapeToTriangulate != null) { outputVertices = new std_vector <Vector2>(mShapeToTriangulate.getPoints()); for (int i = 0; i < mShapeToTriangulate.getSegCount(); ++i) { segmentListIndices.push_back(i); segmentListIndices.push_back(mShapeToTriangulate.getBoundedIndex(i + 1)); } } else if (mMultiShapeToTriangulate != null) { outputVertices = new std_vector <Vector2>(mMultiShapeToTriangulate.getPoints()); int index = 0; for (int i = 0; i < mMultiShapeToTriangulate.getShapeCount(); ++i) { Shape shape = mMultiShapeToTriangulate.getShape((uint)i); for (int j = 0; j < shape.getSegCount(); j++) { segmentListIndices.push_back(index + j); segmentListIndices.push_back(index + shape.getBoundedIndex(j + 1)); } index += shape.getSegCount(); } } else if (mSegmentListToTriangulate != null) { //std_map<Vector2, int, Vector2Comparator> backMap; std_map <Vector2, int> backMap = new std_map <Vector2, int>(new Vector2Comparator()); //for (std::vector<Segment2D>::iterator it = mSegmentListToTriangulate->begin(); it!= mSegmentListToTriangulate->end(); it++) foreach (var it in mSegmentListToTriangulate) { if ((it.mA - it.mB).SquaredLength < 1e-6) { continue; } //std::map<Vector2, int, Vector2Comparator>::iterator it2 = backMap.find(it->mA); int it2_pos = backMap.find(it.mA); //if (it2 != backMap.end()) if (it2_pos != -1) { //segmentListIndices.push_back(it2->second); segmentListIndices.push_back(backMap[it.mA]); } else { //backMap[it->mA] = outputVertices.size(); backMap.insert(it.mA, outputVertices.size()); segmentListIndices.push_back(outputVertices.size()); outputVertices.push_back(it.mA); } //it2 = backMap.find(it.mB); it2_pos = backMap.find(it.mB); //if (it2 != backMap.end()) if (it2_pos != -1) { //segmentListIndices.push_back(it2.second); segmentListIndices.push_back(backMap[it.mB]); } else { //backMap[it->mB] = outputVertices.size(); backMap.insert(it.mB, outputVertices.size()); segmentListIndices.push_back(outputVertices.size()); outputVertices.push_back(it.mB); } } if (mManualSuperTriangle != null) { Triangle superTriangle = new Triangle(outputVertices); for (int i = 0; i < 3; i++) { //std::map<Vector2, int, Vector2Comparator>::iterator it = backMap.find(mManualSuperTriangle->mPoints[i]); int it_pos = backMap.find(mManualSuperTriangle.mPoints[i]); //if (it != backMap.end()) if (it_pos != -1) { //segmentListIndices.push_back(it->second); //superTriangle.i[i] = it->second; superTriangle.i[i] = backMap[mManualSuperTriangle.mPoints[i]]; } else { //backMap[mManualSuperTriangle->mPoints[i]] = outputVertices.size(); backMap.insert(mManualSuperTriangle.mPoints[i], outputVertices.size()); //segmentListIndices.push_back(outputVertices.size()); superTriangle.i[i] = outputVertices.size(); outputVertices.push_back(mManualSuperTriangle.mPoints[i]); } } dtb.push_back(superTriangle); } } //Utils::log("Triangulator preparation : " + StringConverter::toString(mTimer.getMicroseconds() / 1000.0f) + " ms"); delaunay(outputVertices, ref dtb); //Utils::log("Triangulator delaunay : " + StringConverter::toString(mTimer.getMicroseconds() / 1000.0f) + " ms"); // Add contraints _addConstraints(ref dtb, outputVertices, segmentListIndices); //Utils::log("Triangulator constraints : " + StringConverter::toString(mTimer.getMicroseconds() / 1000.0f) + " ms"); //Outputs index buffer //for (DelaunayTriangleBuffer::iterator it = dtb.begin(); it!=dtb.end(); ++it) foreach (var it in dtb) { if (!it.isDegenerate()) { output.push_back(it.i[0]); output.push_back(it.i[1]); output.push_back(it.i[2]); } } // Remove super triangle if (mRemoveOutside) { outputVertices.pop_back(); outputVertices.pop_back(); outputVertices.pop_back(); } //Utils::log("Triangulator output : " + StringConverter::toString(mTimer.getMicroseconds() / 1000.0f) + " ms"); }
//----------------------------------------------------------------------- // //ORIGINAL LINE: void _findAllIntersections(const Shape& STLAllocator<U, AllocPolicy>, List<IntersectionInShape>& intersections) const private void _findAllIntersections(Shape other, ref std_vector<IntersectionInShape> intersections) { for (ushort i = 0; i < getSegCount(); i++) { Segment2D seg1 = new Segment2D(getPoint(i), getPoint(i + 1)); for (ushort j = 0; j < other.getSegCount(); j++) { Segment2D seg2 = new Segment2D(other.getPoint(j), other.getPoint(j + 1)); Vector2 intersect = new Vector2(); if (seg1.findIntersect(seg2, ref intersect)) { IntersectionInShape inter = new IntersectionInShape(i, j, intersect); // check if intersection is "borderline" : too near to a vertex if ((seg1.mA - intersect).SquaredLength < 1e-8) { inter.onVertex[0] = true; } if ((seg1.mB - intersect).SquaredLength < 1e-8) { inter.onVertex[0] = true; inter.index[0]++; } if ((seg2.mA - intersect).SquaredLength < 1e-8) { inter.onVertex[1] = true; } if ((seg2.mB - intersect).SquaredLength < 1e-8) { inter.onVertex[1] = true; inter.index[1]++; } intersections.push_back(inter); } } } }
/// Constructor from a single shape public MultiShape(Shape shape) { mShapes.push_back(shape); }