public bool tessellate(ref Options options, ref Rect clip, iPolylinePath poly, ref Guid hashFront) { eClipResult result = path.buildClippedPolylines(poly, clip, options.transform, options.precision, options.stroke.width); clipResultBack = result; if (result == eClipResult.ClippedOut) { return(clearBackBuffer()); } Guid hash = poly.hash; if (hash == hashFront) { // Same polyline was used to generate the current front buffer. // Return false to skip buffers swap. return(false); } if (hash == hashBack) { return(true); } hashBack = hash; if (result == eClipResult.FillsEntireViewport) { var fillOptions = options.fill; if (!fillOptions.HasFlag(eBuildFilledMesh.FilledMesh)) { return(clearBackBuffer()); } // When there're no visible edges of the path, no point in doing VAA, will be clipped out fillOptions &= ~eBuildFilledMesh.VAA; poly.createMesh(backBuffer, fillOptions, 0); return(true); } if (options.stroke.width <= 0) { poly.createMesh(backBuffer, options.fill, options.pixel); } else if (options.fill == eBuildFilledMesh.None) { poly.createMesh(backBuffer, options.stroke); } else if (options.separateStrokeMesh) { poly.createMesh(backBuffer, options.fill, options.pixel); poly.createMesh(extraStroke.backBuffer, options.stroke); } else { poly.createMesh(backBuffer, options.fill, options.pixel, options.stroke); } return(true); }
/// <summary>Build both meshes</summary> public static void createMesh(this iPolylinePath path, iTriangleMesh result, eBuildFilledMesh filledMesh, float pixel, sStrokeInfo strokeInfo) { unsafe { sStrokeInfo *si = &strokeInfo; path.createMesh(result, filledMesh, pixel, ( IntPtr)si); } }
/// <summary>Clip the polyline to viewport, using specified clipping rectangle</summary> public static eClipResult clip(this iPolylinePath source, iPolylinePath dest, Rect clipRect, Matrix3x2 transform, float strokeWidth = 0) { unsafe { Rect *clip = &clipRect; source.clip(strokeWidth, ref transform, (IntPtr)clip, dest, out var res); return(res); } }
/// <summary>Tessellate splines and clip the result to viewport, using specified clipping rectangle</summary> public static eClipResult buildClippedPolylines(this iPathGeometry path, iPolylinePath poly, Rect clipRect, Matrix3x2 transform, float precision, float strokeWidth = 0) { unsafe { Rect *clip = &clipRect; path.buildPolylines(precision, strokeWidth, ref transform, (IntPtr)clip, poly, out var res); return(res); } }
public static iPolylinePath getTemp(iVrmacDraw factory) { iPolylinePath tmp = tempPolyline; if (null != tmp) { return(tmp); } tmp = factory.createPolylinePath(); tempPolyline = tmp; return(tmp); }
/// <summary>Access polylines generated by path geometry.</summary> /// <remarks>Despite the name, this method doesn’t download anything. /// Instead, it provides a read-only view of the data stored in unmanaged memory, in std::vector<Vector2> C++ containers.</remarks> public static void downloadPolylines(this iPolylinePath path, PolylineDelegate poly) { Span <sPolylineFigure> figures = stackalloc sPolylineFigure[path.info.figuresCount]; path.getFigures(ref figures.GetPinnableReference()); int figureIndex = 0; foreach (var f in figures) { if (f.vertexCount > 0) { var verts = Unsafe.readSpan <Vector2>(f.firstVertexPointer, f.vertexCount); poly(figureIndex, verts, f.isFilled, f.isClosed); } figureIndex++; } }
void threadMain2() { DequedJob job; iPolylinePath tempPoly = TempPolylines.getTemp(factory); Rect clipRect; lock (queues.syncRoot) { clipRect = getClippingRect(); job = queues.dequeue(); if (!job) { threadFinished(); return; } } bool updated = job.tessellate(ref clipRect, tempPoly); while (true) { lock (queues.syncRoot) { if (job.isSameOptions()) { queues.completed(ref job, updated); updated = false; job = queues.dequeue(); if (!job) { threadFinished(); return; } } } bool u = job.tessellate(ref clipRect, tempPoly); updated = updated || u; } }
/// <summary>Build just the filled mesh</summary> public static void createMesh(this iPolylinePath path, iTriangleMesh result, eBuildFilledMesh filledMesh, float pixel) { Debug.Assert(filledMesh != eBuildFilledMesh.None); path.createMesh(result, filledMesh, pixel, IntPtr.Zero); }
/// <summary>Clip the polyline to viewport, using default clipping rectangle</summary> public static eClipResult clip(this iPolylinePath source, iPolylinePath dest, Matrix3x2 transform, float strokeWidth = 0) { source.clip(strokeWidth, ref transform, IntPtr.Zero, dest, out var res); return(res); }
/// <summary>Tessellate splines and clip the result to viewport, using default clipping rectangle</summary> public static eClipResult buildClippedPolylines(this iPathGeometry path, iPolylinePath poly, Matrix3x2 transform, float precision, float strokeWidth = 0) { path.buildPolylines(precision, strokeWidth, ref transform, IntPtr.Zero, poly, out var res); return(res); }
public bool tessellate(ref Rect clip, iPolylinePath poly) { return(meshes.tessellate(ref options, ref clip, poly, ref hash)); }