// * // * Builds the mesh into the given TriangleBuffer // * @param buffer The TriangleBuffer on where to append the mesh. // * @exception Ogre::InvalidStateException Either shape or multishape must be defined! // * @exception Ogre::InvalidStateException Required parameter is zero! // //----------------------------------------------------------------------- // //ORIGINAL LINE: void addToTriangleBuffer(TriangleBuffer& buffer) const public override void addToTriangleBuffer(ref TriangleBuffer buffer) { if (mMultiShapeToExtrude.getShapeCount() == 0) { OGRE_EXCEPT("Ogre::Exception::ERR_INVALID_STATE", "At least one shape must be defined!", "Procedural::Extruder::addToTriangleBuffer(Procedural::TriangleBuffer)"); } ; // Triangulate the begin and end caps if (mCapped && mMultiShapeToExtrude.isClosed()) { GlobalMembers._extrudeCapImpl(ref buffer, mMultiShapeToExtrude, mMultiExtrusionPath, mScaleTracks, mRotationTracks); } // Extrude the paths contained in multiExtrusionPath for (uint j = 0; j < mMultiExtrusionPath.getPathCount(); ++j) { Path extrusionPath = mMultiExtrusionPath.getPath((int)j); Track rotationTrack = null; if (mRotationTracks.find(j) != -1) // mRotationTracks.end()) { { rotationTrack = mRotationTracks[j]; //mRotationTracks.find(j).second; extrusionPath = extrusionPath.mergeKeysWithTrack(mRotationTracks[j]); // (*mRotationTracks.find(j).second); } Track scaleTrack = null; if (mScaleTracks.find(j) != -1) // mScaleTracks.end()) { { rotationTrack = mScaleTracks[j]; //mScaleTracks.find(j).second; extrusionPath = extrusionPath.mergeKeysWithTrack(mScaleTracks[j]); // (*mScaleTracks.find(j).second); } Track pathTextureTrack = null; if (mPathTextureTracks.find(j) != -1) // mPathTextureTracks.end()) { { pathTextureTrack = mPathTextureTracks[j]; //mPathTextureTracks.find(j).second; extrusionPath = extrusionPath.mergeKeysWithTrack(mPathTextureTracks[j]); //(*mPathTextureTracks.find(j).second); } std_vector <std_pair <uint, uint> > segs = mMultiExtrusionPath.getNoIntersectionParts(j); //for (List<std.pair<uint, uint>>.Enumerator it = segs.GetEnumerator(); it.MoveNext(); ++it) { foreach (var it in segs) { for (uint i = 0; i < mMultiShapeToExtrude.getShapeCount(); i++) { Shape shapeToExtrude = mMultiShapeToExtrude.getShape(i); Track shapeTextureTrack = null; if (mShapeTextureTracks.find(i) != -1) // mShapeTextureTracks.end()) { { shapeTextureTrack = mShapeTextureTracks[i]; //mShapeTextureTracks.find(i).second; shapeToExtrude.mergeKeysWithTrack(shapeTextureTrack); } GlobalMembers._extrudeBodyImpl(ref buffer, shapeToExtrude, extrusionPath, (int)it.first, (int)it.second, shapeTextureTrack, rotationTrack, scaleTrack, pathTextureTrack); } } // Make the intersections //typedef std::vector<PathCoordinate> PathIntersection; std_vector <std_vector <MultiPath.PathCoordinate> > intersections = mMultiExtrusionPath.getIntersections(); //for (List<MultiPath.PathIntersection>.Enumerator it = intersections.GetEnumerator(); it.MoveNext(); ++it) { foreach (var it in intersections) { for (uint i = 0; i < mMultiShapeToExtrude.getShapeCount(); i++) { Track shapeTextureTrack = null; if (mShapeTextureTracks.find(i) != -1) // mShapeTextureTracks.end()) { shapeTextureTrack = mShapeTextureTracks[i]; //mShapeTextureTracks.find(i).second; } GlobalMembers._extrudeIntersectionImpl(ref buffer, it, mMultiExtrusionPath, mMultiShapeToExtrude.getShape(i), shapeTextureTrack); } } } }
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; } } } }