public void InsertPointInContours(List <int> contourIndices, int pointA, int pointB) { // Insert a point between to points if (contourIndices == null) { return; } int pointCount = PointCount; if (pointA == -1 || pointA >= pointCount || pointB < 0 || pointB >= pointCount) { return; } int newPointIndex = -1; foreach (int contourIndex in contourIndices) { // Find index in contour between points A and B int insertAt; do { List <PointOccurence> occurencesA = points[pointA].occurences; List <PointOccurence> occurencesB = points[pointB].occurences; if (occurencesA == null || occurencesB == null) { return; } insertAt = -1; foreach (PointOccurence occA in occurencesA) { // Search point A occurence in contour if (occA.contourIndex == contourIndex) { // Find point B occurence that's next to point A in contour int findOccB = occurencesB.FindIndex(occ => occ.contourIndex == contourIndex && (occ.indexInContour == occA.indexInContour + 1 || occ.indexInContour == occA.indexInContour - 1)); if (findOccB != -1) { // Insert index is higher index between indices A and B PointOccurence occB = occurencesB[findOccB]; insertAt = occB.indexInContour > occA.indexInContour ? occB.indexInContour : occA.indexInContour; // If inserted point has not been created yet, create it if (newPointIndex == -1) { newPointIndex = PointCount; AddPoint((points[pointA].position + points[pointB].position) / 2f); } // Insert new point in contour InsertPointInContour(contourIndex, insertAt, newPointIndex); break; } } } }while (insertAt != -1); } }
public void DestroyAllPointlessContours() { // Get rid of empty contours contourShapes.RemoveAll(contour => contour.Length == 0); // Destroy contour indices in bloc List <List <int> > contourPointIndices = GetAllContours(false); if (contourPointIndices == null) { return; } List <int> pointlessContourIndices = new List <int>(); for (int cti = 0, ctcount = contourPointIndices.Count; cti < ctcount; cti++) { if (contourPointIndices[cti].Count == 0) { pointlessContourIndices.Add(cti); } } if (pointlessContourIndices.Count == 0) { return; } // Remove occurences and shift indices for (int pti = -1, ptCount = PointCount; pti < ptCount; pti++) { Point pt = pti == -1 ? bufferPoint : points[pti]; List <PointOccurence> occurences = pt.occurences; if (occurences == null) { continue; } // Remove occurences if in in pointless contour occurences.RemoveAll(occ => pointlessContourIndices.Contains(occ.contourIndex)); // Shift higher contours indices for (int occi = 0, occCount = occurences.Count; occi < occCount; occi++) { PointOccurence occ = occurences[occi]; int decrementIndex = pointlessContourIndices.FindAll(cti => occ.contourIndex > cti).Count; occ.contourIndex -= decrementIndex; } // Set occurences pt.occurences = occurences; if (pti == -1) { bufferPoint = pt; } else { points[pti] = pt; } } }
public void RemoveContourAt(int contourIndex) { // Remove all points from the contour List <int> pointIndices = GetContour(contourIndex, true); foreach (int pti in pointIndices) { RemovePointFromContour(pti, contourIndex); } // Decrement higher contour indices in all point occurences, including buffer point for (int pti = -1, ptCount = PointCount; pti < ptCount; pti++) { Point point = pti == -1 ? bufferPoint : points[pti]; int occurenceCount = point.OccurenceCount; if (occurenceCount == 0) { continue; } List <PointOccurence> occurences = point.occurences; bool changeOccurences = false; for (int occi = 0; occi < occurenceCount; occi++) { PointOccurence occ = occurences[occi]; if (occ.contourIndex > contourIndex) { changeOccurences = true; occ.contourIndex--; occurences[occi] = occ; } } if (changeOccurences) { point.occurences = occurences; if (pti == -1) { bufferPoint = point; } else { points[pti] = point; } } } // Remove contour contourShapes.RemoveAt(contourIndex); changes |= BlocChanges.ContourRemoved; }
public void InsertPointInContour(int contourIndex, int insertAt, int pointIndex) { // Add a point at a specific place in a contour if (pointIndex < 0 || pointIndex >= PointCount) { return; } List <int> contourPoints = GetContour(contourIndex, true); if (insertAt < 0 || insertAt >= contourPoints.Count) { Debug.LogError("Index out of bounds"); return; } // Unless contour has undefined point at this place, we need to make place in contour for new point if (contourPoints[insertAt] != -1) { for (int pti = 0, pointCount = PointCount; pti < pointCount; pti++) { int occurenceCount = points[pti].OccurenceCount; for (int occi = 0; occi < occurenceCount; occi++) { // Make place = change occurences that are later in the contour PointOccurence occ = points[pti].occurences[occi]; if (occ.contourIndex == contourIndex && occ.indexInContour >= insertAt) { occ.indexInContour++; points[pti].occurences[occi] = occ; } } } } // Add contour to point points[pointIndex].occurences.Add(new PointOccurence() { contourIndex = contourIndex, indexInContour = insertAt }); // Add position to contour contourShapes[contourIndex].InsertPosition(insertAt, GetPosition(pointIndex)); }
public void RemovePointFromContour(int pointIndex, int contourIndex, bool preserveLoop = true) { // Remove all point occurence in contour if (points == null || pointIndex < -1 || pointIndex >= points.Count) { return; } // Removing one point from one contour impacts all the points that are following (higher index) in this contour, including undefined points List <int> pointIndices = GetContour(contourIndex, true); if (pointIndices.Count == 0) { return; } // If contour is looped and we break it by removing the point, restore it later - unless specified otherwise bool restoreLoop = preserveLoop && IsContourLooped(contourIndex) && pointIndex == pointIndices[0]; // Ensure we get all occurences of the removed point in the selected contour, as there can be several int findPointIndexInContour = pointIndices.IndexOf(pointIndex); while (findPointIndexInContour != -1) { // Update following points in contour for (int i = findPointIndexInContour, ptCount = pointIndices.Count; i < ptCount; i++) { int pti = pointIndices[i]; Point follow_pt = pti == -1 ? bufferPoint : points[pti]; for (int occi = 0, occCount = follow_pt.OccurenceCount; occi < occCount; occi++) { PointOccurence occ = follow_pt.occurences[occi]; if (occ.contourIndex == contourIndex && occ.indexInContour > findPointIndexInContour) { occ.indexInContour--; if (pti != -1) { points[pti].occurences[occi] = occ; } else { bufferPoint.occurences[occi] = occ; } } } } // Remove contour from point, and position from contour if (pointIndex != -1) { points[pointIndex].occurences.RemoveAll(occ => occ.contourIndex == contourIndex); contourShapes[contourIndex].RemovePosition(findPointIndexInContour); } // Or remove point from buffer else { bufferPoint.occurences.RemoveAll(occ => occ.contourIndex == contourIndex); } // Get updated contour to see if the point to removed is still mentionned in it pointIndices = GetContour(contourIndex, true); findPointIndexInContour = pointIndices.IndexOf(pointIndex); } // Loop contour back again if needed if (restoreLoop) { LoopContour(contourIndex, true); } }