public void AddContour(ContourVertex[] vertices, ContourOrientation forceOrientation) { if (_mesh == null) { _mesh = new Mesh(); } bool reverse = false; if (forceOrientation != ContourOrientation.Original) { float area = SignedArea(vertices); reverse = (forceOrientation == ContourOrientation.Clockwise && area < 0.0f) || (forceOrientation == ContourOrientation.CounterClockwise && area > 0.0f); } MeshUtils.Edge e = null; for (int i = 0; i < vertices.Length; ++i) { if (e == null) { e = _mesh.MakeEdge(); _mesh.Splice(e, e._Sym); } else { // Create a new vertex and edge which immediately follow e // in the ordering around the left face. _mesh.SplitEdge(e); e = e._Lnext; } int index = reverse ? vertices.Length - 1 - i : i; // The new vertex is now e._Org. e._Org._coords = vertices[index].Position; e._Org._data = vertices[index].Data; // The winding of an edge says how the winding number changes as we // cross from the edge's right face to its left face. We add the // vertices in such an order that a CCW contour will add +1 to // the winding number of the region inside the contour. e._winding = 1; e._Sym._winding = -1; } }
public void Tessellate(WindingRule windingRule, ElementType elementType, int polySize, CombineCallback combineCallback) { _vertices = null; _elements = null; _windingRule = windingRule; _combineCallback = combineCallback; if (_mesh == null) { return; } // Determine the polygon normal and project vertices onto the plane // of the polygon. ProjectPolygon(); // ComputeInterior computes the planar arrangement specified // by the given contours, and further subdivides this arrangement // into regions. Each region is marked "inside" if it belongs // to the polygon, according to the rule given by windingRule. // Each interior region is guaranteed be monotone. ComputeInterior(); // If the user wants only the boundary contours, we throw away all edges // except those which separate the interior from the exterior. // Otherwise we tessellate all the regions marked "inside". if (elementType == ElementType.BoundaryContours) { SetWindingNumber(1, true); } else { TessellateInterior(); } _mesh.Check(); if (elementType == ElementType.BoundaryContours) { OutputContours(); } else { OutputPolymesh(elementType, polySize); } _mesh = null; }
public Tess() { _normal = Vec3.Zero; _bminX = _bminY = _bmaxX = _bmaxY = 0.0f; _windingRule = WindingRule.EvenOdd; _mesh = null; _vertices = null; _vertexCount = 0; _elements = null; _elementCount = 0; }