public float[] BuildSmoothBorders(Figure[] figures, bool isClosedFigure, out int borderTriangleStripCount) { _expandCoords.Clear(); int total_b_triangleStripCount = 0; for (int i = 0; i < figures.Length; ++i) { Figure fig = figures[i]; if (i == 0) { //first BuildSmoothBorders(fig.coordXYs, fig.IsClosedFigure, _expandCoords, out int b_triangleStripCount); total_b_triangleStripCount += b_triangleStripCount; } else { int latestCoordCount = _expandCoords.Count; //add degenerative triangle //for GLES30 consider=>GL_PRIMITIVE_RESTART_FIXED_INDEX //see https://developer.apple.com/library/archive/documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/TechniquesforWorkingwithVertexData/TechniquesforWorkingwithVertexData.html //To merge two triangle strips, duplicate the last vertex of the first strip and the first vertex of the second strip, //as shown in Figure 8-6. When this strip is submitted to OpenGL ES, //triangles DEE, EEF, EFF, and FFG are considered degenerate and not processed or rasterized. float prev_x = _expandCoords[latestCoordCount - 4]; float prev_y = _expandCoords[latestCoordCount - 3]; float prev_z = _expandCoords[latestCoordCount - 2]; float prev_w = _expandCoords[latestCoordCount - 1]; _expandCoords.Add(prev_x); _expandCoords.Add(prev_y); _expandCoords.Add(prev_z); _expandCoords.Add(prev_w); latestCoordCount += 4;//*** //since we use a single coord //preserve space (4 coords) for degenerative triangles //(see restore later) _expandCoords.Add(0); _expandCoords.Add(0); _expandCoords.Add(0); _expandCoords.Add(0); //----- BuildSmoothBorders(fig.coordXYs, fig.IsClosedFigure, _expandCoords, out int b_triangleStripCount); //----- //restore- 4 coord of latest expandCoords set _expandCoords[latestCoordCount] = _expandCoords[latestCoordCount + 4]; _expandCoords[latestCoordCount + 1] = _expandCoords[latestCoordCount + 5]; _expandCoords[latestCoordCount + 2] = _expandCoords[latestCoordCount + 6]; _expandCoords[latestCoordCount + 3] = _expandCoords[latestCoordCount + 7]; total_b_triangleStripCount += b_triangleStripCount + 1; //*** +1 for a degenerative triangle } } borderTriangleStripCount = total_b_triangleStripCount; float[] result = _expandCoords.ToArray(); _expandCoords.Clear(); // return(result); }
public FigureContainer(MultiFigures multiFig) { _figure = null; _multiFig = multiFig; }
public FigureContainer(Figure fig) { _figure = fig; _multiFig = null; }
public float[] GetAreaTess(TessTool tess, Tesselate.Tesselator.WindingRuleType windingRuleType, TessTriangleTechnique tessTechnique) { #if DEBUG if (this.TessTriangleTech == 0) { } #endif if (TessTriangleTech != tessTechnique) { //re tess again this.TessTriangleTech = tessTechnique; //*** using (ReusableCoordList.Borrow(out ReusableCoordList resuableCoordList)) { ArrayList <float> coordXYs = resuableCoordList._coordXYs; ArrayList <int> contourEndPoints = resuableCoordList._contourEndPoints; Figure fig = null; for (int i = 0; i < _figures.Length; ++i) { fig = _figures[i]; coordXYs.Append(fig.coordXYs); if (fig.IsClosedFigure) { //for tess,if close figure coordXYs.Append(fig.coordXYs[0]); coordXYs.Append(fig.coordXYs[1]); } contourEndPoints.Append(coordXYs.Count - 1); } if (this.TessTriangleTech == TessTriangleTechnique.DrawArray) { tess.WindingRuleType = windingRuleType; return(_areaTess = tess.TessAsTriVertexArray( coordXYs.ToArray(), contourEndPoints.ToArray(), out _tessAreaVertexCount)); } else { tess.WindingRuleType = windingRuleType; _areaTessIndexList = tess.TessAsTriIndexArray( coordXYs.ToArray(), contourEndPoints.ToArray(), out _areaTess, out _tessAreaVertexCount); return(_areaTess); } } } else { //if equal return(_areaTess); } }
public void PreparePolygons(Figure fig, List <Poly2Tri.Polygon> outputPolyons) { PreparePolygons(fig.coordXYs, outputPolyons); }
public FigureContainer Build(PixelFarm.Drawing.VertexStore vxs) { //vxs must be flatten vxs. #if DEBUG double prevX = 0; double prevY = 0; #endif double prevMoveToX = 0; double prevMoveToY = 0; _xylist.Clear(); _figs.Clear(); //TODO: reivew here //about how to reuse this list //result... RectBoundsAccum rectBoundsAccum = new RectBoundsAccum(); rectBoundsAccum.Init(); int index = 0; VertexCmd cmd; while ((cmd = vxs.GetVertex(index++, out double x, out double y)) != VertexCmd.NoMore) { switch (cmd) { case VertexCmd.MoveTo: #if DEBUG prevX = x; prevY = y; #endif prevMoveToX = x; prevMoveToY = y; _xylist.Add((float)x); _xylist.Add((float)y); rectBoundsAccum.Update(x, y); break; case VertexCmd.LineTo: _xylist.Add((float)x); _xylist.Add((float)y); #if DEBUG prevX = x; prevY = y; #endif rectBoundsAccum.Update(x, y); break; case VertexCmd.Close: { //don't add //_xylist.Add((float)prevMoveToX); //_xylist.Add((float)prevMoveToY); #if DEBUG prevX = prevMoveToX; prevY = prevMoveToY; #endif //----------- Figure newfig = new Figure(_xylist.ToArray(), rectBoundsAccum.ToRectF()); newfig.IsClosedFigure = true; _figs.Add(newfig); //----------- _xylist.Clear(); //clear temp list rectBoundsAccum.Init(); } break; case VertexCmd.NoMore: goto EXIT_LOOP; default: throw new System.NotSupportedException(); } } EXIT_LOOP: if (_figs.Count == 0) { Figure newfig = new Figure(_xylist.ToArray(), rectBoundsAccum.ToRectF()); newfig.IsClosedFigure = false; return(new FigureContainer(newfig)); } // if (_xylist.Count > 1) { #if DEBUG prevX = prevMoveToX; prevY = prevMoveToY; #endif // Figure newfig = new Figure(_xylist.ToArray(), rectBoundsAccum.ToRectF()); newfig.IsClosedFigure = true; //? _figs.Add(newfig); } if (_figs.Count == 1) { Figure fig = _figs[0]; _figs.Clear(); return(new FigureContainer(fig)); } else { MultiFigures multiFig = new MultiFigures(_figs.ToArray()); _figs.Clear(); return(new FigureContainer(multiFig)); } }