/// <summary> /// Paints on a WriteableBitmap with a stylized airbrush /// </summary> /// <param name="bmp">The bitmap to modify</param> /// <param name="from">The starting point of the stroke</param> /// <param name="to">The end point of the stroke</param> /// <param name="color">The color of the stroke</param> /// <param name="size">The size of the stroke</param> public static unsafe void Airbrush(WriteableBitmap bmp, Point from, Point to, Color color, int size) { Random r = new Random(); if (bmp == null) return; bmp.Lock(); // Create a line segment representation MyLine line = new MyLine(from, to); // Get a bounding box for the painted area BoundingBox bitmapbounds = new BoundingBox(); BoundingBox linebounds = new BoundingBox(); bitmapbounds.AddPoint(0, 0, 0); bitmapbounds.AddPoint(bmp.PixelWidth - 1, bmp.PixelHeight - 1, 0); linebounds.AddPoint((int)from.X, (int)from.Y, size + AirbrushRadiu); linebounds.AddPoint((int)to.X, (int)to.Y, size + AirbrushRadiu); linebounds.Clip(bitmapbounds); UInt32* start = (UInt32*)bmp.BackBuffer.ToPointer(); int stride = bmp.BackBufferStride / sizeof(UInt32); // Move from 'from' to 'to' along timestep intervals, with one dot painted per interval for (int i = 0; i < AirbrushDots; i++) { int x, y; line.Interpolate(i, AirbrushDots, out x, out y); int dist = r.Next() % size; double angle = r.NextDouble() * 2 * Math.PI; double dx = Math.Cos(angle) * dist; double dy = Math.Sqrt(dist * dist - dx * dx); if (angle > Math.PI) dy = -dy; int bx = x + (int)dx; int by = y + (int)dy; BoundingBox dotbounds = new BoundingBox(); dotbounds.AddPoint(bx, by, AirbrushRadiu); dotbounds.Clip(bitmapbounds); for (int k = dotbounds.Top, row = 0; k < dotbounds.Bottom; k++, y++, row++) for (int j = dotbounds.Left, col = 0; j < dotbounds.Right; j++, col++) AlphaBlended(start + stride * k + j, Color.FromArgb(AirbrushBytes[row][col], color.R, color.G, color.B)); } bmp.AddDirtyRect(new Int32Rect(linebounds.Left, linebounds.Top, linebounds.Width, linebounds.Height)); bmp.Unlock(); }
/// <summary> /// Erases paint on a pbgra32 WriteableBitmap /// </summary> /// <param name="bmp">The bitmap to modify</param> /// <param name="from">The starting point of the stroke</param> /// <param name="to">The end point of the stroke</param> /// <param name="size">The stroke size</param> public static unsafe void Erase(WriteableBitmap bmp, Point from, Point to, int size) { if (bmp == null) { return; } bmp.Lock(); // Intermediate storage of the square of the size int sizesize = size * size; // Create a line segment representation to compare distance to MyLine linesegment = new MyLine(from, to); // Get a bounding box for the line segment BoundingBox bitmapbounds = new BoundingBox(); BoundingBox segmentbounds = new BoundingBox(); bitmapbounds.AddPoint(0, 0, 0); bitmapbounds.AddPoint(bmp.PixelWidth - 1, bmp.PixelHeight - 1, 0); segmentbounds.AddPoint((int)from.X, (int)from.Y, size); segmentbounds.AddPoint((int)to.X, (int)to.Y, size); segmentbounds.Clip(bitmapbounds); // Get a pointer to the back buffer (we use an int pointer here, since we can safely assume a 32-bit pixel format) Int32 *start = (Int32 *)bmp.BackBuffer.ToPointer(); // Move the starting pixel to the x offset start += segmentbounds.Left; // Loop through the relevant portion of the image and figure out which pixels need to be erased for (int y = segmentbounds.Top; y < segmentbounds.Bottom; y++) { Int32 *pixel = start + bmp.BackBufferStride / sizeof(Int32) * y; for (int x = segmentbounds.Left; x < segmentbounds.Right; x++) { if (linesegment.DistanceSquared(x, y) <= sizesize) { *pixel = 0; } // Move to the next pixel pixel++; } } bmp.AddDirtyRect(new Int32Rect(segmentbounds.Left, segmentbounds.Top, segmentbounds.Width, segmentbounds.Height)); bmp.Unlock(); }
internal override void IncorporatePointIntoBoundingBox(BoundingBox boundingBox) { foreach (DiffuseOnlyVertex vertex in vertices_) { boundingBox.AddPoint(vertex.Position); } }
protected override void Add(Point2D p, int idx, bool bCalcWindingOrderAndEpsilon) { TriangulationPoint pt; if (p is TriangulationPoint) { pt = p as TriangulationPoint; } else { pt = new TriangulationPoint(p.X, p.Y); } if (idx < 0) { MPoints.Add(pt); } else { MPoints.Insert(idx, pt); } BoundingBox = BoundingBox.AddPoint(pt); if (bCalcWindingOrderAndEpsilon) { if (WindingOrder == WindingOrderType.Unknown) { WindingOrder = CalculateWindingOrder(); } Epsilon = CalculateEpsilon(); } }
private void CalculateBounds() { _boundingBox = new Rect2D(); foreach (Point2D pt in MPoints) { BoundingBox = BoundingBox.AddPoint(pt); } }
public static unsafe void Erase(WriteableBitmap bmp, Point from, Point to, int size) { if (bmp == null) { return; } bmp.Lock(); int sizesize = size * size; LineSegment linesegment = new LineSegment(from, to); BoundingBox bitmapbounds = new BoundingBox(); BoundingBox segmentbounds = new BoundingBox(); bitmapbounds.AddPoint(0, 0, 0); bitmapbounds.AddPoint(bmp.PixelWidth - 1, bmp.PixelHeight - 1, 0); segmentbounds.AddPoint((int)from.X, (int)from.Y, size); segmentbounds.AddPoint((int)to.X, (int)to.Y, size); segmentbounds.Clip(bitmapbounds); Int32 *start = (Int32 *)bmp.BackBuffer.ToPointer(); start += segmentbounds.Left; for (int y = segmentbounds.Top; y < segmentbounds.Bottom; y++) { Int32 *pixel = start + bmp.BackBufferStride / sizeof(Int32) * y; for (int x = segmentbounds.Left; x < segmentbounds.Right; x++) { if (linesegment.DistanceSquared(x, y) <= sizesize) { *pixel = 0; } pixel++; } } bmp.AddDirtyRect(new Int32Rect(segmentbounds.Left, segmentbounds.Top, segmentbounds.Width, segmentbounds.Height)); bmp.Unlock(); }
protected PointSet(IEnumerable <TriangulationPoint> bounds) { //Points = new List<TriangulationPoint>(); foreach (TriangulationPoint p in bounds) { Add(p, -1, false); // Only the initial points are counted toward min/max x/y as they // are considered to be the boundaries of the point-set BoundingBox = BoundingBox.AddPoint(p); } Epsilon = CalculateEpsilon(); WindingOrder = WindingOrderType.Unknown; // not valid for a point-set }
protected override void AddRange(IEnumerator <Point2D> iter, WindingOrderType windingOrder) { if (iter == null) { return; } if (WindingOrder == WindingOrderType.Unknown && Count == 0) { WindingOrder = windingOrder; } bool bReverseReadOrder = (WindingOrder != WindingOrderType.Unknown) && (windingOrder != WindingOrderType.Unknown) && (WindingOrder != windingOrder); bool bAddedFirst = true; int startCount = MPoints.Count; iter.Reset(); while (iter.MoveNext()) { TriangulationPoint pt; if (iter.Current is TriangulationPoint) { pt = iter.Current as TriangulationPoint; } else { pt = new TriangulationPoint(iter.Current.X, iter.Current.Y); } if (!bAddedFirst) { bAddedFirst = true; MPoints.Add(pt); } else if (bReverseReadOrder) { MPoints.Insert(startCount, pt); } else { MPoints.Add(pt); } BoundingBox = BoundingBox.AddPoint(iter.Current); } if (WindingOrder == WindingOrderType.Unknown && windingOrder == WindingOrderType.Unknown) { WindingOrder = CalculateWindingOrder(); } Epsilon = CalculateEpsilon(); }
/// <summary> /// Computes the bounding box of cell <paramref name="j"/> /// </summary> /// <param name="j">local cell index</param> /// <param name="bb"> /// on exit, the bounding box of cell j. /// </param> public void GetCellBoundingBox(int j, BoundingBox bb) { int D = bb.D; if (bb.D != m_Owner.SpatialDimension) { throw new ArgumentException("wrong dimension of bounding box."); } bb.Clear(); MultidimensionalArray Points = m_Owner.m_VertexData.Coordinates; double[] pt = new double[D]; foreach (int iVtx in this.CellVertices[j]) { Points.GetRow(iVtx, pt, 0, 1); bb.AddPoint(pt); } }
protected virtual void Add(Point2D p, int idx, bool bCalcWindingOrderAndEpsilon) { if (idx < 0) { MPoints.Add(p); } else { MPoints.Insert(idx, p); } BoundingBox = BoundingBox.AddPoint(p); if (bCalcWindingOrderAndEpsilon) { if (_windingOrder == WindingOrderType.Unknown) { _windingOrder = CalculateWindingOrder(); } Epsilon = CalculateEpsilon(); } }
public static unsafe void Butterfly(WriteableBitmap bmp, Point from, Point to, Color color, int size) { AirbrushDots = 2000; AirbrushDotRadius = 3; Random r = new Random(); if (bmp == null) { return; } bmp.Lock(); // Create a line segment representation LineSegment segment = new LineSegment(from, to); // Get a bounding box for the painted area BoundingBox bitmapbounds = new BoundingBox(); BoundingBox segmentbounds = new BoundingBox(); bitmapbounds.AddPoint(0, 0, 0); bitmapbounds.AddPoint(bmp.PixelWidth - 1, bmp.PixelHeight - 1, 0); segmentbounds.AddPoint((int)from.X, (int)from.Y, 1500); segmentbounds.AddPoint((int)to.X, (int)to.Y, 1500); segmentbounds.Clip(bitmapbounds); UInt32 *start = (UInt32 *)bmp.BackBuffer.ToPointer(); int stride = bmp.BackBufferStride / sizeof(UInt32); // Move from 'from' to 'to' along timestep0 intervals, with one dot painted per interval int ran; if (size < 10) { ran = (r.Next() % (300 - size * 20)) + 1; } else if (size < 20) { ran = (r.Next() % (450 - size * 20)) + 1; } else if (size < 30) { ran = (r.Next() % (600 - size * 30)) + 1; } else if (size < 40) { ran = (r.Next() % (1400 - size * 20)) + 1; } else { ran = (r.Next() % (3200 - size * 20)) + 1; } for (int i = 0; i < AirbrushDots; i++) { int x, y; temp = i; segment.Interpolate(i, AirbrushDots, out x, out y); int bx = x + temp; int by = y - (temp * temp) / ran; if (temp % 4 == 0) { if (ran % 2 == 0) { bx = x + (temp * temp) / ran; by = y - temp; } else { bx = x + temp; by = y - (temp * temp) / ran; } } else if (temp % 4 == 1) { if (ran % 2 == 0) { bx = x + (temp * temp) / ran; by = y + temp; } else { bx = x + temp; by = y + (temp * temp) / ran; } } else if (temp % 4 == 2) { if (ran % 2 == 0) { bx = x - (temp * temp) / ran; by = y + temp; } else { bx = x - temp; by = y + (temp * temp) / ran; } } else if (temp % 4 == 3) { if (ran % 2 == 0) { bx = x - (temp * temp) / ran; by = y - temp; } else { bx = x - temp; by = y - (temp * temp) / ran; } } if (Math.Sqrt((bx - x) * (bx - x) + (by - y) * (by - y)) > size * 10) { continue; } BoundingBox dotbounds = new BoundingBox(); dotbounds.AddPoint(bx, by, AirbrushDotRadius); dotbounds.Clip(bitmapbounds); for (int k = dotbounds.Top, row = 0; k < dotbounds.Bottom; k++, y++, row++) { for (int j = dotbounds.Left, col = 0; j < dotbounds.Right; j++, col++) { WriteAlphaBlended(start + stride * k + j, Color.FromArgb(AirbrushDotKernel[row][col], color.R, color.G, color.B)); } } } bmp.AddDirtyRect(new Int32Rect(segmentbounds.Left, segmentbounds.Top, segmentbounds.Width, segmentbounds.Height)); bmp.Unlock(); }
/// <summary> /// Erases paint on a WriteableBitmap /// </summary> /// <param name="bmp">The bitmap to modify</param> /// <param name="from">The starting point of the stroke</param> /// <param name="to">The end point of the stroke</param> /// <param name="size">The stroke size</param> public static unsafe void Erase(WriteableBitmap bmp, Point from, Point to, int size) { if (bmp == null) return; bmp.Lock(); // Intermediate storage of the square of the size int area = size * size; // Create a line segment representation to compare distance to MyLine line = new MyLine(from, to); // Get a bounding box for the line segment BoundingBox bitmapbounds = new BoundingBox(); BoundingBox linebounds = new BoundingBox(); bitmapbounds.AddPoint(0, 0, 0); bitmapbounds.AddPoint(bmp.PixelWidth - 1, bmp.PixelHeight - 1, 0); linebounds.AddPoint((int)from.X, (int)from.Y, size); linebounds.AddPoint((int)to.X, (int)to.Y, size); linebounds.Clip(bitmapbounds); // Get a pointer to the back buffer (we use an int pointer here, since we can safely assume a 32-bit pixel format) Int32* start = (Int32*)bmp.BackBuffer.ToPointer(); // Move the starting pixel to the x offset start += linebounds.Left; // Loop through the relevant portion of the image and figure out which pixels need to be erased for (int y = linebounds.Top; y < linebounds.Bottom; y++) { Int32* pixel = start + bmp.BackBufferStride / sizeof(Int32) * y; for (int x = linebounds.Left; x < linebounds.Right; x++) { if (line.DistanceSquared(x, y) <= area) *pixel = 0; // Move to the next pixel pixel++; } } bmp.AddDirtyRect(new Int32Rect(linebounds.Left, linebounds.Top, linebounds.Width, linebounds.Height)); bmp.Unlock(); }
/// <summary> /// Paints on a WriteableBitmap like a paintbrush /// </summary> /// <param name="bmp">The bitmap to modify</param> /// <param name="from">The starting point of the stroke</param> /// <param name="to">The end point of the stroke</param> /// <param name="previous">The point prior to the 'from' point, or null</param> /// <param name="color">The color of the brush</param> /// <param name="size">The stroke size</param> public static unsafe void Brush(WriteableBitmap bmp, Point from, Point to, Point? previous, Color color, int size) { if (bmp == null) return; bmp.Lock(); // Intermediate storage of the square of the size int area = size * size; uint flatcolor = (uint)((int)color.A << 24) + (uint)((int)color.R << 16) + (uint)((int)color.G << 8) + color.B; // Create a line segment representation to compare distance to MyLine line = new MyLine(from, to); // Get a bounding box for the line segment BoundingBox bitmapbounds = new BoundingBox(); BoundingBox linebounds = new BoundingBox(); bitmapbounds.AddPoint(0, 0, 0); bitmapbounds.AddPoint(bmp.PixelWidth - 1, bmp.PixelHeight - 1, 0); linebounds.AddPoint((int)from.X, (int)from.Y, size); linebounds.AddPoint((int)to.X, (int)to.Y, size); linebounds.Clip(bitmapbounds); // Get a pointer to the back buffer (we use an int pointer here, since we can safely assume a 32-bit pixel format) UInt32* start = (UInt32*)bmp.BackBuffer.ToPointer(); // Move the starting pixel to the x offset start += linebounds.Left; if (previous.HasValue) { MyLine previoussegment = new MyLine(previous.Value, from); // Loop through the relevant portion of the image and figure out which pixels need to be erased for (int y = linebounds.Top; y < linebounds.Bottom; y++) { UInt32* pixel = start + bmp.BackBufferStride / sizeof(UInt32) * y; for (int x = linebounds.Left; x < linebounds.Right; x++) { if (line.DistanceSquared(x, y) <= area && previoussegment.DistanceSquared(x, y) > area) { if (color.A == 255) *pixel = flatcolor; else AlphaBlended(pixel, color); } // Move to the next pixel pixel++; } } } else { // Loop through the relevant portion of the image and figure out which pixels need to be erased for (int y = linebounds.Top; y < linebounds.Bottom; y++) { UInt32* pixel = start + bmp.BackBufferStride / sizeof(UInt32) * y; for (int x = linebounds.Left; x < linebounds.Right; x++) { if (line.DistanceSquared(x, y) <= area) { if (color.A == 255) *pixel = flatcolor; else AlphaBlended(pixel, color); } // Move to the next pixel pixel++; } } } bmp.AddDirtyRect(new Int32Rect(linebounds.Left, linebounds.Top, linebounds.Width, linebounds.Height)); bmp.Unlock(); }
public override bool GetLocalBoundingBox(ref BoundingBox bbox) { PathNodeShape[] nodes = this.PathNodes; if (nodes == null || nodes.Length == 0) return false; bbox = new BoundingBox(); foreach (PathNodeShape node in nodes) bbox.AddPoint(node.LocalSpacePosition); bbox.AddBorder(5.0f * EditorManager.Settings.GlobalUnitScaling); return true; }
/// <summary> /// Constructs suitable quadrature rules cells in /// <paramref name="mask"/>. /// </summary> /// <param name="mask"> /// Cells for which quadrature rules shall be created /// </param> /// <param name="order"> /// Desired order of the moment-fitting system. Assuming that /// <see cref="surfaceRuleFactory"/> integrates the basis polynomials /// exactly over the zero iso-contour (which it usually /// doesn't!), the resulting quadrature rules will be exact up to this /// order. /// </param> /// <returns>A set of quadrature rules</returns> /// <remarks> /// Since the selected level set is generally discontinuous across cell /// boundaries, this method does not make use of the fact that /// neighboring cells share edges. That is, the optimization will be /// performed twice for each inner edge in <paramref name="mask"/>. /// </remarks> public IEnumerable <IChunkRulePair <QuadRule> > GetQuadRuleSet(ExecutionMask mask, int order) { using (var tr = new FuncTrace()) { CellMask cellMask = mask as CellMask; if (cellMask == null) { throw new ArgumentException("Mask must be a volume mask", "mask"); } // Note: This is a parallel call, so do this early to avoid parallel confusion localCellIndex2SubgridIndex = new SubGrid(cellMask).LocalCellIndex2SubgridIndex; int maxLambdaDegree = order + 1; int noOfLambdas = GetNumberOfLambdas(maxLambdaDegree); int noOfEdges = LevelSetData.GridDat.Grid.RefElements[0].NoOfFaces; int D = RefElement.SpatialDimension; // Get the basis polynomials and integrate them analytically Polynomial[] basePolynomials = RefElement.GetOrthonormalPolynomials(order).ToArray(); Polynomial[] polynomials = new Polynomial[basePolynomials.Length * D]; for (int i = 0; i < basePolynomials.Length; i++) { Polynomial p = basePolynomials[i]; for (int d = 0; d < D; d++) { Polynomial pNew = p.CloneAs(); for (int j = 0; j < p.Coeff.Length; j++) { pNew.Exponents[j, d]++; pNew.Coeff[j] /= pNew.Exponents[j, d]; pNew.Coeff[j] /= D; // Make sure divergence is Phi again } polynomials[i * D + d] = pNew; } } // basePolynomials[i] == div(polynomials[i*D], ... , polynomials[i*D + D - 1]) lambdaBasis = new PolynomialList(polynomials); if (RestrictNodes) { trafos = new AffineTrafo[mask.NoOfItemsLocally]; foreach (Chunk chunk in mask) { foreach (var cell in chunk.Elements.AsSmartEnumerable()) { CellMask singleElementMask = new CellMask( LevelSetData.GridDat, Chunk.GetSingleElementChunk(cell.Value)); LineAndPointQuadratureFactory.LineQRF lineFactory = this.edgeRuleFactory as LineAndPointQuadratureFactory.LineQRF; if (lineFactory == null) { throw new Exception(); } var lineRule = lineFactory.GetQuadRuleSet(singleElementMask, order).Single().Rule; var pointRule = lineFactory.m_Owner.GetPointFactory().GetQuadRuleSet(singleElementMask, order).Single().Rule; // Also add point rule points since line rule points // are constructed from Gauss rules that do not include // the end points BoundingBox box = new BoundingBox(lineRule.Nodes); box.AddPoints(pointRule.Nodes); int noOfRoots = pointRule.Nodes.GetLength(0); if (noOfRoots <= 1) { // Cell is considered cut because the level set // is very close, but actually isn't. Note that // we can NOT omit the cell (as in the surface // case) as it will be missing in the list of // uncut cells, i.e. this cell would be ignored // completely trafos[localCellIndex2SubgridIndex[cell.Value]] = AffineTrafo.Identity(RefElement.SpatialDimension); continue; } else if (noOfRoots == 2) { // Go a bit into the direction of the normal // from the center between the nodes in order // not to miss regions with strong curvature double[] center = box.Min.CloneAs(); center.AccV(1.0, box.Max); center.ScaleV(0.5); NodeSet centerNode = new NodeSet(RefElement, center); centerNode.LockForever(); MultidimensionalArray normal = LevelSetData.GetLevelSetReferenceNormals(centerNode, cell.Value, 1); MultidimensionalArray dist = LevelSetData.GetLevSetValues(centerNode, cell.Value, 1); double scaling = Math.Sqrt(LevelSetData.GridDat.Cells.JacobiDet[cell.Value]); double[] newPoint = new double[D]; for (int d = 0; d < D; d++) { newPoint[d] = center[d] - normal[0, 0, d] * dist[0, 0] / scaling; } box.AddPoint(newPoint); // Make sure points stay in box for (int d = 0; d < D; d++) { box.Min[d] = Math.Max(box.Min[d], -1); box.Max[d] = Math.Min(box.Max[d], 1); } } MultidimensionalArray preImage = RefElement.Vertices.ExtractSubArrayShallow( new int[] { 0, 0 }, new int[] { D, D - 1 }); MultidimensionalArray image = MultidimensionalArray.Create(D + 1, D); image[0, 0] = box.Min[0]; // Top left image[0, 1] = box.Max[1]; image[1, 0] = box.Max[0]; // Top right image[1, 1] = box.Max[1]; image[2, 0] = box.Min[0]; // Bottom left; image[2, 1] = box.Min[1]; AffineTrafo trafo = AffineTrafo.FromPoints(preImage, image); trafos[localCellIndex2SubgridIndex[cell.Value]] = trafo; } } } LambdaCellBoundaryQuadrature cellBoundaryQuadrature = new LambdaCellBoundaryQuadrature(this, edgeRuleFactory, cellMask); cellBoundaryQuadrature.Execute(); LambdaLevelSetSurfaceQuadrature surfaceQuadrature = new LambdaLevelSetSurfaceQuadrature(this, surfaceRuleFactory, cellMask); surfaceQuadrature.Execute(); // Must happen _after_ all parallel calls (e.g., definition of // the sub-grid or quadrature) in order to avoid problems in // parallel runs if (mask.NoOfItemsLocally == 0) { var empty = new ChunkRulePair <QuadRule> [0]; return(empty); } if (cachedRules.ContainsKey(order)) { order = cachedRules.Keys.Where(cachedOrder => cachedOrder >= order).Min(); CellMask cachedMask = new CellMask(mask.GridData, cachedRules[order].Select(p => p.Chunk).ToArray()); if (cachedMask.Equals(mask)) { return(cachedRules[order]); } else { throw new NotImplementedException( "Case not yet covered yet in combination with caching; deactivate caching to get rid of this message"); } } double[,] quadResults = cellBoundaryQuadrature.Results; foreach (Chunk chunk in mask) { for (int i = 0; i < chunk.Len; i++) { int iSubGrid = localCellIndex2SubgridIndex[chunk.i0 + i]; switch (jumpType) { case JumpTypes.Heaviside: for (int k = 0; k < noOfLambdas; k++) { quadResults[iSubGrid, k] -= surfaceQuadrature.Results[iSubGrid, k]; } break; case JumpTypes.OneMinusHeaviside: for (int k = 0; k < noOfLambdas; k++) { quadResults[iSubGrid, k] += surfaceQuadrature.Results[iSubGrid, k]; } break; case JumpTypes.Sign: for (int k = 0; k < noOfLambdas; k++) { quadResults[iSubGrid, k] -= 2.0 * surfaceQuadrature.Results[iSubGrid, k]; } break; default: throw new NotImplementedException(); } } } BitArray voidCellsArray = new BitArray(LevelSetData.GridDat.Cells.NoOfLocalUpdatedCells); BitArray fullCellsArray = new BitArray(LevelSetData.GridDat.Cells.NoOfLocalUpdatedCells); foreach (Chunk chunk in cellMask) { foreach (var cell in chunk.Elements) { double rhsL2Norm = 0.0; for (int k = 0; k < noOfLambdas; k++) { double entry = quadResults[localCellIndex2SubgridIndex[cell], k]; rhsL2Norm += entry * entry; } if (rhsL2Norm < 1e-14) { // All integrals are zero => cell not really cut // (level set is tangent) and fully in void region voidCellsArray[cell] = true; continue; } double l2NormFirstIntegral = quadResults[localCellIndex2SubgridIndex[cell], 0]; l2NormFirstIntegral *= l2NormFirstIntegral; double rhsL2NormWithoutFirst = rhsL2Norm - l2NormFirstIntegral; // Beware: This check is only sensible if basis is orthonormal on RefElement! if (rhsL2NormWithoutFirst < 1e-14 && Math.Abs(l2NormFirstIntegral - RefElement.Volume) < 1e-14) { // All integrals are zero except integral over first integrand // If basis is orthonormal, this implies that cell is uncut and // fully in non-void region since then // \int_K \Phi_i dV = \int_A \Phi_i dV = \delta_{0,i} // However, we have to compare RefElement.Volume since // integration is performed in reference coordinates! fullCellsArray[cell] = true; } } } var result = new List <ChunkRulePair <QuadRule> >(cellMask.NoOfItemsLocally); CellMask emptyCells = new CellMask(LevelSetData.GridDat, voidCellsArray); foreach (Chunk chunk in emptyCells) { foreach (int cell in chunk.Elements) { QuadRule emptyRule = QuadRule.CreateEmpty(RefElement, 1, RefElement.SpatialDimension); emptyRule.Nodes.LockForever(); result.Add(new ChunkRulePair <QuadRule>( Chunk.GetSingleElementChunk(cell), emptyRule)); } } CellMask fullCells = new CellMask(LevelSetData.GridDat, fullCellsArray); foreach (Chunk chunk in fullCells) { foreach (int cell in chunk.Elements) { QuadRule fullRule = RefElement.GetQuadratureRule(order); result.Add(new ChunkRulePair <QuadRule>( Chunk.GetSingleElementChunk(cell), fullRule)); } } CellMask realCutCells = cellMask.Except(emptyCells).Except(fullCells); if (RestrictNodes) { foreach (Chunk chunk in realCutCells) { foreach (int cell in chunk.Elements) { CellMask singleElementMask = new CellMask( LevelSetData.GridDat, Chunk.GetSingleElementChunk(cell)); AffineTrafo trafo = trafos[localCellIndex2SubgridIndex[cell]]; Debug.Assert(Math.Abs(trafo.Matrix.Determinant()) > 1e-10); NodeSet nodes = GetNodes(noOfLambdas).CloneAs(); NodeSet mappedNodes = new NodeSet(RefElement, trafo.Transform(nodes)); mappedNodes.LockForever(); // Remove nodes in negative part MultidimensionalArray levelSetValues = LevelSetData.GetLevSetValues(mappedNodes, cell, 1); List <int> nodesToBeCopied = new List <int>(mappedNodes.GetLength(0)); for (int n = 0; n < nodes.GetLength(0); n++) { if (levelSetValues[0, n] >= 0.0) { nodesToBeCopied.Add(n); } } NodeSet reducedNodes = new NodeSet( this.RefElement, nodesToBeCopied.Count, D); for (int n = 0; n < nodesToBeCopied.Count; n++) { for (int d = 0; d < D; d++) { reducedNodes[n, d] = mappedNodes[nodesToBeCopied[n], d]; } } reducedNodes.LockForever(); QuadRule optimizedRule = GetOptimizedRule( cell, trafo, reducedNodes, quadResults, order); result.Add(new ChunkRulePair <QuadRule>( singleElementMask.Single(), optimizedRule)); } } } else { // Use same nodes in all cells QuadRule[] optimizedRules = GetOptimizedRules( realCutCells, GetNodes(noOfLambdas), quadResults, order); int ruleIndex = 0; foreach (Chunk chunk in realCutCells) { foreach (var cell in chunk.Elements) { result.Add(new ChunkRulePair <QuadRule>( Chunk.GetSingleElementChunk(cell), optimizedRules[ruleIndex])); ruleIndex++; } } } cachedRules[order] = result.OrderBy(p => p.Chunk.i0).ToArray(); return(cachedRules[order]); } }
/// <summary> /// Paints on a pbgra32 WriteableBitmap with a stylized airbrush /// </summary> /// <param name="bmp">The bitmap to modify</param> /// <param name="from">The starting point of the stroke</param> /// <param name="to">The end point of the stroke</param> /// <param name="color">The color of the stroke</param> /// <param name="size">The size of the stroke</param> public static unsafe void Airbrush(WriteableBitmap bmp, Point from, Point to, Color color, int size) { Random r = new Random(); if (bmp == null) { return; } bmp.Lock(); // Create a line segment representation MyLine segment = new MyLine(from, to); // Get a bounding box for the painted area BoundingBox bitmapbounds = new BoundingBox(); BoundingBox segmentbounds = new BoundingBox(); bitmapbounds.AddPoint(0, 0, 0); bitmapbounds.AddPoint(bmp.PixelWidth - 1, bmp.PixelHeight - 1, 0); segmentbounds.AddPoint((int)from.X, (int)from.Y, size + AirbrushRadio); segmentbounds.AddPoint((int)to.X, (int)to.Y, size + AirbrushRadio); segmentbounds.Clip(bitmapbounds); UInt32 *start = (UInt32 *)bmp.BackBuffer.ToPointer(); int stride = bmp.BackBufferStride / sizeof(UInt32); // Move from 'from' to 'to' along timestep intervals, with one dot painted per interval for (int i = 0; i < AirbrushDots; i++) { int x, y; segment.Interpolate(i, AirbrushDots, out x, out y); int dist = r.Next() % size; double angle = r.NextDouble() * 2 * Math.PI; double dx = Math.Cos(angle) * dist; double dy = Math.Sqrt(dist * dist - dx * dx); if (angle > Math.PI) { dy = -dy; } int bx = x + (int)dx; int by = y + (int)dy; BoundingBox dotbounds = new BoundingBox(); dotbounds.AddPoint(bx, by, AirbrushRadio); dotbounds.Clip(bitmapbounds); for (int k = dotbounds.Top, row = 0; k < dotbounds.Bottom; k++, y++, row++) { for (int j = dotbounds.Left, col = 0; j < dotbounds.Right; j++, col++) { WriteAlphaBlended(start + stride * k + j, Color.FromArgb(AirbrushBytes[row][col], color.R, color.G, color.B)); } } } bmp.AddDirtyRect(new Int32Rect(segmentbounds.Left, segmentbounds.Top, segmentbounds.Width, segmentbounds.Height)); bmp.Unlock(); }
// From Eric Jordan's convex decomposition library /// <summary> /// Merges all parallel edges in the list of vertices /// </summary> /// <param name="tolerance"></param> public void MergeParallelEdges(double tolerance) { if (Count <= 3) { // Can't do anything useful here to a triangle return; } bool[] mergeMe = new bool[Count]; int newNVertices = Count; //Gather points to process for (int i = 0; i < Count; ++i) { int lower = (i == 0) ? (Count - 1) : (i - 1); int middle = i; int upper = (i == Count - 1) ? (0) : (i + 1); double dx0 = this[middle].X - this[lower].X; double dy0 = this[middle].Y - this[lower].Y; double dx1 = this[upper].Y - this[middle].X; double dy1 = this[upper].Y - this[middle].Y; double norm0 = Math.Sqrt(dx0 * dx0 + dy0 * dy0); double norm1 = Math.Sqrt(dx1 * dx1 + dy1 * dy1); if (!(norm0 > 0.0 && norm1 > 0.0) && newNVertices > 3) { //Merge identical points mergeMe[i] = true; --newNVertices; } dx0 /= norm0; dy0 /= norm0; dx1 /= norm1; dy1 /= norm1; double cross = dx0 * dy1 - dx1 * dy0; double dot = dx0 * dx1 + dy0 * dy1; if (Math.Abs(cross) < tolerance && dot > 0 && newNVertices > 3) { mergeMe[i] = true; --newNVertices; } else { mergeMe[i] = false; } } if (newNVertices == Count || newNVertices == 0) { return; } int currIndex = 0; // Copy the vertices to a new list and clear the old Point2DList oldVertices = new Point2DList(this); Clear(); for (int i = 0; i < oldVertices.Count; ++i) { if (mergeMe[i] || newNVertices == 0 || currIndex == newNVertices) { continue; } if (currIndex >= newNVertices) { throw new Exception("Point2DList::MergeParallelEdges - currIndex[ " + currIndex + "] >= newNVertices[" + newNVertices + "]"); } MPoints.Add(oldVertices[i]); BoundingBox = BoundingBox.AddPoint(oldVertices[i]); ++currIndex; } _windingOrder = CalculateWindingOrder(); Epsilon = CalculateEpsilon(); }
public static unsafe void Test2(WriteableBitmap bmp, Point from, Point to, Color color, int size) { Random r = new Random(); AirbrushDots = 500; AirbrushDotRadius = 2; if (bmp == null) { return; } bmp.Lock(); // Create a line segment representation LineSegment segment = new LineSegment(from, to); // Get a bounding box for the painted area BoundingBox bitmapbounds = new BoundingBox(); BoundingBox segmentbounds = new BoundingBox(); bitmapbounds.AddPoint(0, 0, 0); bitmapbounds.AddPoint(bmp.PixelWidth - 1, bmp.PixelHeight - 1, 0); segmentbounds.AddPoint((int)from.X, (int)from.Y, size + AirbrushDotRadius); segmentbounds.AddPoint((int)to.X, (int)to.Y, size + AirbrushDotRadius); segmentbounds.Clip(bitmapbounds); UInt32 *start = (UInt32 *)bmp.BackBuffer.ToPointer(); int stride = bmp.BackBufferStride / sizeof(UInt32); // Move from 'from' to 'to' along timestep intervals, with one dot painted per interval for (int i = 0; i < AirbrushDots; i++) { int x, y; segment.Interpolate(i, AirbrushDots, out x, out y); int dist = r.Next() % size; double angle = r.NextDouble() * 2 * Math.PI; double dx = Math.Cos(angle) * dist; double dy = Math.Sqrt(dist * dist - dx * dx); if (angle > Math.PI) { dy = -dy; } int bx = x + (int)dx; int by = y + (int)dy; //세로로 rainbow if (i < 50) { if ((i % 5) == 0) { color = Colors.Red; // color = Color.FromArgb(20, 132, 200, 249); bx = x + 0; by = y + 0; } if ((i % 5) == 1) { color = Colors.Red; //color = Color.FromArgb(15, 133, 199, 247); bx = x + 0; by = y + 3; } if ((i % 5) == 2) { color = Colors.Red; //color = Color.FromArgb(15, 133, 199, 247); bx = x + 0; by = y - 3; } if ((i % 5) == 3) { color = Colors.Red; //color = Color.FromArgb(10, 124, 201, 255); bx = x + 0; by = y + 6; } if ((i % 5) == 4) { color = Colors.Red; //color = Color.FromArgb(10, 124, 201, 255); bx = x + 0; by = y - 6; } } if (i >= 50 && i < 100) { if ((i % 5) == 0) { color = Colors.Orange; // color = Color.FromArgb(20, 132, 200, 249); bx = x + 0; by = y + 0; } if ((i % 5) == 1) { color = Colors.Orange; //color = Color.FromArgb(15, 133, 199, 247); bx = x + 0; by = y + 3; } if ((i % 5) == 2) { color = Colors.Orange; //color = Color.FromArgb(15, 133, 199, 247); bx = x + 0; by = y - 3; } if ((i % 5) == 3) { color = Colors.Orange; //color = Color.FromArgb(10, 124, 201, 255); bx = x + 0; by = y + 6; } if ((i % 5) == 4) { color = Colors.Orange; //color = Color.FromArgb(10, 124, 201, 255); bx = x + 0; by = y - 6; } } if (i >= 100 && i < 150) { if ((i % 5) == 0) { color = Colors.Yellow; // color = Color.FromArgb(20, 132, 200, 249); bx = x + 0; by = y + 0; } if ((i % 5) == 1) { color = Colors.Yellow; //color = Color.FromArgb(15, 133, 199, 247); bx = x + 0; by = y + 3; } if ((i % 5) == 2) { color = Colors.Yellow; //color = Color.FromArgb(15, 133, 199, 247); bx = x + 0; by = y - 3; } if ((i % 5) == 3) { color = Colors.Yellow; //color = Color.FromArgb(10, 124, 201, 255); bx = x + 0; by = y + 6; } if ((i % 5) == 4) { color = Colors.Yellow; //color = Color.FromArgb(10, 124, 201, 255); bx = x + 0; by = y - 6; } } if (i >= 150 && i < 200) { if ((i % 5) == 0) { color = Colors.Green; // color = Color.FromArgb(20, 132, 200, 249); bx = x + 0; by = y + 0; } if ((i % 5) == 1) { color = Colors.Green; //color = Color.FromArgb(15, 133, 199, 247); bx = x + 0; by = y + 3; } if ((i % 5) == 2) { color = Colors.Green; //color = Color.FromArgb(15, 133, 199, 247); bx = x + 0; by = y - 3; } if ((i % 5) == 3) { color = Colors.Green; //color = Color.FromArgb(10, 124, 201, 255); bx = x + 0; by = y + 6; } if ((i % 5) == 4) { color = Colors.Green; //color = Color.FromArgb(10, 124, 201, 255); bx = x + 0; by = y - 6; } } if (i >= 200 && i < 250) { if ((i % 5) == 0) { color = Colors.Blue; // color = Color.FromArgb(20, 132, 200, 249); bx = x + 0; by = y + 0; } if ((i % 5) == 1) { color = Colors.Blue; //color = Color.FromArgb(15, 133, 199, 247); bx = x + 0; by = y + 3; } if ((i % 5) == 2) { color = Colors.Blue; //color = Color.FromArgb(15, 133, 199, 247); bx = x + 0; by = y - 3; } if ((i % 5) == 3) { color = Colors.Blue; //color = Color.FromArgb(10, 124, 201, 255); bx = x + 0; by = y + 6; } if ((i % 5) == 4) { color = Colors.Blue; //color = Color.FromArgb(10, 124, 201, 255); bx = x + 0; by = y - 6; } } if (i >= 250 && i < 300) { if ((i % 5) == 0) { color = Colors.Indigo; // color = Color.FromArgb(20, 132, 200, 249); bx = x + 0; by = y + 0; } if ((i % 5) == 1) { color = Colors.Indigo; //color = Color.FromArgb(15, 133, 199, 247); bx = x + 0; by = y + 3; } if ((i % 5) == 2) { color = Colors.Indigo; //color = Color.FromArgb(15, 133, 199, 247); bx = x + 0; by = y - 3; } if ((i % 5) == 3) { color = Colors.Indigo; //color = Color.FromArgb(10, 124, 201, 255); bx = x + 0; by = y + 6; } if ((i % 5) == 4) { color = Colors.Indigo; //color = Color.FromArgb(10, 124, 201, 255); bx = x + 0; by = y - 6; } } if (i >= 300 && i < 350) { if ((i % 5) == 0) { color = Colors.BlueViolet; // color = Color.FromArgb(20, 132, 200, 249); bx = x + 0; by = y + 0; } if ((i % 5) == 1) { color = Colors.BlueViolet; //color = Color.FromArgb(15, 133, 199, 247); bx = x + 0; by = y + 3; } if ((i % 5) == 2) { color = Colors.BlueViolet; //color = Color.FromArgb(15, 133, 199, 247); bx = x + 0; by = y - 3; } if ((i % 5) == 3) { color = Colors.BlueViolet; //color = Color.FromArgb(10, 124, 201, 255); bx = x + 0; by = y + 6; } if ((i % 5) == 4) { color = Colors.BlueViolet; //color = Color.FromArgb(10, 124, 201, 255); bx = x + 0; by = y - 6; } } BoundingBox dotbounds = new BoundingBox(); dotbounds.AddPoint(bx, by, AirbrushDotRadius); dotbounds.Clip(bitmapbounds); for (int k = dotbounds.Top, row = 0; k < dotbounds.Bottom; k++, y++, row++) { for (int j = dotbounds.Left, col = 0; j < dotbounds.Right; j++, col++) { WriteAlphaBlended(start + stride * k + j, Color.FromArgb(AirbrushDotKernel[row][col], color.R, color.G, color.B)); } } } bmp.AddDirtyRect(new Int32Rect(segmentbounds.Left, segmentbounds.Top, segmentbounds.Width, segmentbounds.Height)); bmp.Unlock(); }
public static unsafe void Brush(WriteableBitmap bmp, Point from, Point to, Point?previous, Color color, int size) { if (bmp == null) { return; } bmp.Lock(); int sizesize = size * size; uint flatcolor = (uint)((int)color.A << 24) + (uint)((int)color.R << 16) + (uint)((int)color.G << 8) + color.B; LineSegment linesegment = new LineSegment(from, to); BoundingBox bitmapbounds = new BoundingBox(); BoundingBox segmentbounds = new BoundingBox(); bitmapbounds.AddPoint(0, 0, 0); bitmapbounds.AddPoint(bmp.PixelWidth - 1, bmp.PixelHeight - 1, 0); segmentbounds.AddPoint((int)from.X, (int)from.Y, size); segmentbounds.AddPoint((int)to.X, (int)to.Y, size); segmentbounds.Clip(bitmapbounds); UInt32 *start = (UInt32 *)bmp.BackBuffer.ToPointer(); start += segmentbounds.Left; if (previous.HasValue) { LineSegment previoussegment = new LineSegment(previous.Value, from); for (int y = segmentbounds.Top; y < segmentbounds.Bottom; y++) { UInt32 *pixel = start + bmp.BackBufferStride / sizeof(UInt32) * y; for (int x = segmentbounds.Left; x < segmentbounds.Right; x++) { if (linesegment.DistanceSquared(x, y) <= sizesize && previoussegment.DistanceSquared(x, y) > sizesize) { if (color.A == 255) { *pixel = flatcolor; } else { WriteAlphaBlended(pixel, color); } } pixel++; } } } else { for (int y = segmentbounds.Top; y < segmentbounds.Bottom; y++) { UInt32 *pixel = start + bmp.BackBufferStride / sizeof(UInt32) * y; for (int x = segmentbounds.Left; x < segmentbounds.Right; x++) { if (linesegment.DistanceSquared(x, y) <= sizesize) { if (color.A == 255) { *pixel = flatcolor; } else { WriteAlphaBlended(pixel, color); } } pixel++; } } } bmp.AddDirtyRect(new Int32Rect(segmentbounds.Left, segmentbounds.Top, segmentbounds.Width, segmentbounds.Height)); bmp.Unlock(); }
public void AddBlock(string block, Action action) { if (action == Action.New) { if (Loaded) { gcode.Rows.Clear(); } Reset(); commands.Clear(); gcode.BeginLoadData(); filename = block; } else if (block != null && block.Trim().Length > 0) { try { if (Parser.ParseBlock(block.Trim(), false)) { gcode.Rows.Add(new object[] { LineNumber++, block, block.Length + 1, true, Parser.ProgramEnd, "", false }); while (commands.Count > 0) { gcode.Rows.Add(new object[] { LineNumber++, commands.Dequeue(), 20, true, false, "", false }); } } } catch //(Exception e) { // } } if (action == Action.End) { gcode.EndLoadData(); // GCodeParser.Save(@"d:\tokens.xml", Tokens); foreach (GCodeToken token in Tokens) { //min_feed = Math.Min(min_feed, token.f); //max_feed = Math.Max(max_feed, token.f); if (token is GCLinearMotion) { BoundingBox.AddPoint(((GCLinearMotion)token).X, ((GCLinearMotion)token).Y, ((GCLinearMotion)token).Z); } else if (token is GCArc) { BoundingBox.AddPoint(((GCArc)token).X, ((GCArc)token).Y, ((GCArc)token).Z); // TODO: Expand... } else if (token is GCCannedDrill) { BoundingBox.AddPoint(((GCCannedDrill)token).X, ((GCCannedDrill)token).Y, ((GCCannedDrill)token).Z); } } if (max_feed == double.MinValue) { min_feed = 0.0; max_feed = 0.0; } BoundingBox.Normalize(); FileChanged?.Invoke(filename); } }
/// <summary> /// Paints on a pbgra32 WriteableBitmap like a paintbrush /// </summary> /// <param name="bmp">The bitmap to modify</param> /// <param name="from">The starting point of the stroke</param> /// <param name="to">The end point of the stroke</param> /// <param name="previous">The point prior to the 'from' point, or null</param> /// <param name="color">The color of the brush</param> /// <param name="size">The stroke size</param> public static unsafe void Brush(WriteableBitmap bmp, Point from, Point to, Point?previous, Color color, int size) { if (bmp == null) { return; } bmp.Lock(); // Intermediate storage of the square of the size int sizesize = size * size; uint flatcolor = (uint)((int)color.A << 24) + (uint)((int)color.R << 16) + (uint)((int)color.G << 8) + color.B; // Create a line segment representation to compare distance to MyLine linesegment = new MyLine(from, to); // Get a bounding box for the line segment BoundingBox bitmapbounds = new BoundingBox(); BoundingBox segmentbounds = new BoundingBox(); bitmapbounds.AddPoint(0, 0, 0); bitmapbounds.AddPoint(bmp.PixelWidth - 1, bmp.PixelHeight - 1, 0); segmentbounds.AddPoint((int)from.X, (int)from.Y, size); segmentbounds.AddPoint((int)to.X, (int)to.Y, size); segmentbounds.Clip(bitmapbounds); // Get a pointer to the back buffer (we use an int pointer here, since we can safely assume a 32-bit pixel format) UInt32 *start = (UInt32 *)bmp.BackBuffer.ToPointer(); // Move the starting pixel to the x offset start += segmentbounds.Left; if (previous.HasValue) { MyLine previoussegment = new MyLine(previous.Value, from); // Loop through the relevant portion of the image and figure out which pixels need to be erased for (int y = segmentbounds.Top; y < segmentbounds.Bottom; y++) { UInt32 *pixel = start + bmp.BackBufferStride / sizeof(UInt32) * y; for (int x = segmentbounds.Left; x < segmentbounds.Right; x++) { if (linesegment.DistanceSquared(x, y) <= sizesize && previoussegment.DistanceSquared(x, y) > sizesize) { if (color.A == 255) { *pixel = flatcolor; } else { WriteAlphaBlended(pixel, color); } } // Move to the next pixel pixel++; } } } else { // Loop through the relevant portion of the image and figure out which pixels need to be erased for (int y = segmentbounds.Top; y < segmentbounds.Bottom; y++) { UInt32 *pixel = start + bmp.BackBufferStride / sizeof(UInt32) * y; for (int x = segmentbounds.Left; x < segmentbounds.Right; x++) { if (linesegment.DistanceSquared(x, y) <= sizesize) { if (color.A == 255) { *pixel = flatcolor; } else { WriteAlphaBlended(pixel, color); } } // Move to the next pixel pixel++; } } } bmp.AddDirtyRect(new Int32Rect(segmentbounds.Left, segmentbounds.Top, segmentbounds.Width, segmentbounds.Height)); bmp.Unlock(); }
public static unsafe void Test4(WriteableBitmap bmp, Point from, Point to, Color color, int size) { AirbrushDots = 1000; AirbrushDotRadius = 4; if (bmp == null) { return; } bmp.Lock(); // Create a line segment representation LineSegment segment = new LineSegment(from, to); // Get a bounding box for the painted area BoundingBox bitmapbounds = new BoundingBox(); BoundingBox segmentbounds = new BoundingBox(); bitmapbounds.AddPoint(0, 0, 0); bitmapbounds.AddPoint(bmp.PixelWidth - 1, bmp.PixelHeight - 1, 0); segmentbounds.AddPoint((int)from.X, (int)from.Y, size + 500 + AirbrushDotRadius); segmentbounds.AddPoint((int)to.X, (int)to.Y, size + 500 + AirbrushDotRadius); segmentbounds.Clip(bitmapbounds); UInt32 *start = (UInt32 *)bmp.BackBuffer.ToPointer(); int stride = bmp.BackBufferStride / sizeof(UInt32); // Move from 'from' to 'to' along timestep intervals, with one dot painted per interval for (int i = 0; i < AirbrushDots; i++) { int x, y; segment.Interpolate(i, AirbrushDots, out x, out y); //int dist =size; //double angle =2 * Math.PI; //double dx = Math.Cos(angle) * dist; //double dy = Math.Sqrt(dist * dist - dx * dx); //if (angle > Math.PI) dy = -dy; int bx = x; int by = y; if (i % 4 == 0) { bx = x + 500; by = y + 500; } else if (i % 4 == 1) { bx = x - 500; by = y + 500; } else if (i % 4 == 2) { bx = x + 500; by = y - 500; } else if (i % 4 == 3) { bx = x - 500; by = y - 500; } //switch (i % 4) //{ // case 0: // bx= //} BoundingBox dotbounds = new BoundingBox(); dotbounds.AddPoint(bx, by, AirbrushDotRadius); dotbounds.Clip(bitmapbounds); for (int k = dotbounds.Top, row = 0; k < dotbounds.Bottom; k++, y++, row++) { for (int j = dotbounds.Left, col = 0; j < dotbounds.Right; j++, col++) { WriteAlphaBlended(start + stride * k + j, Color.FromArgb(AirbrushDotKernel[row][col], color.R, color.G, color.B)); } } } bmp.AddDirtyRect(new Int32Rect(segmentbounds.Left, segmentbounds.Top, segmentbounds.Width, segmentbounds.Height)); bmp.Unlock(); }
void Start() { List <Atom> atoms; List <List <int> > connections; string model_name; try { model_name = ParseInputModelFile(); PDBParser.ParseAtomsAndConnections(@"Assets/MModels/" + model_name, out atoms, out connections); } catch (System.IO.IOException) { print("Parsing input error"); return; } /* Spawn the objects */ foreach (Atom atom in atoms) { /* Units in Nano meters */ Vector3 atom_position = new Vector3(atom.x_, atom.y_, atom.z_); atoms_bounding_box_.AddPoint(atom_position); /* Instantiate the atom */ GameObject temp = Instantiate(prefab_atom, atom_position, Quaternion.identity); temp.transform.parent = transform; temp.isStatic = this.gameObject.isStatic; /* Find ISphere component, and set the atom information */ ISphere isphere = temp.GetComponent <ISphere>(); isphere.atom_ = atom; ispheres_.Add(isphere); /* Insert to the dictionaries used */ InsertToAtomsDictionary(isphere); InsertToResiudesDictionary(isphere); InsertToChainsDictionary(isphere); } /* Parse connections, currently the application does not do something with these connections */ foreach (List <int> c in connections) { int atom_id = c[0]; for (int i = 1; i < c.Count; i++) { ISphere connection_isphere = ispheres_[c[i]]; ispheres_[atom_id].connections_.Add(connection_isphere); } } /* Spawn bonds */ Transform bonds_transform = transform.GetChild(0); int bonds = 0; /* For all resisudes */ foreach (KeyValuePair <int, List <ISphere> > value in residue_dictionary) { /* Get combinations of two atoms */ List <ISphere> resiude_atoms = value.Value; for (int ia = 0; ia < resiude_atoms.Count; ia++) { ISphere a = resiude_atoms[ia]; Vector3 a_position = a.transform.position; float a_covalent_radius = AtomicRadii.GetCovalentRadius(a.atom_.element_); for (int ib = 0; ib < resiude_atoms.Count; ib++) { if (!(ia > ib)) { continue; } ISphere b = resiude_atoms[ib]; Vector3 b_position = b.transform.position; float b_covalent_radius = AtomicRadii.radii_covalent[b.atom_.element_]; /* If their distance is smaller then the sume of radius + plus a bias, then spawn a bond */ float distance = Vector3.Distance(a_position, b_position); if (distance <= a_covalent_radius + b_covalent_radius + 0.015) { bonds++; GameObject temp = Instantiate(prefab_bond, a_position, Quaternion.identity); temp.transform.parent = bonds_transform; temp.isStatic = this.gameObject.isStatic; /* Rotate it accordingly */ Vector3 direction = b_position - a_position; Quaternion toRotation = Quaternion.FromToRotation(new Vector3(0, 1, 0), direction); temp.transform.rotation = toRotation; /* Set size and radius */ ICylinder icylinder = temp.GetComponent <ICylinder>(); icylinder.radius_ = AtomicRadii.ball_and_stick_bond_radius; icylinder.height_ = distance; } } } } Debug.Log("Spawned: " + bonds + " bonds"); /* Position the model and the camera in the world */ SetCameraAndPanelBoxPosition(atoms_bounding_box_); bonds_selected_[0] = null; bonds_selected_[1] = null; /* Set some default info on the world panel */ SELECTION_MODE_SPHERE_RADIUS = AtomicRadii.ball_and_stick_radius * 5.0f; transform.GetChild(1).GetComponent <ModePanel>().SetRadius(SELECTION_MODE_SPHERE_RADIUS); info_ui_ = Camera.main.transform.Find("AtomInfoBox").GetComponent <AtomInfoBox>(); }
public void AddBlock(string block, Action action) { if (action == Action.New) { if (Loaded) { gcode.Rows.Clear(); } Reset(); commands.Clear(); gcode.BeginLoadData(); filename = block; } else if (block != null && block.Trim().Length > 0) { try { bool isComment; block = block.Trim(); if (Parser.ParseBlock(ref block, false, out isComment)) { gcode.Rows.Add(new object[] { LineNumber++, block, block.Length + 1, true, isComment, Parser.ProgramEnd, "", false }); while (commands.Count > 0) { block = commands.Dequeue(); gcode.Rows.Add(new object[] { LineNumber++, block, block.Length + 1, true, false, false, "", false }); } } } catch //(Exception e) { // } } if (action == Action.End) { gcode.EndLoadData(); #if DEBUG System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch(); stopWatch.Start(); #endif // Calculate program limits (bounding box) GCodeEmulator emu = new GCodeEmulator(true); foreach (var cmd in emu.Execute(Tokens)) { if (cmd.Token is GCArc) { BoundingBox.AddBoundingBox((cmd.Token as GCArc).GetBoundingBox(emu.Plane, new double[] { cmd.Start.X, cmd.Start.Y, cmd.Start.Z }, emu.DistanceMode == DistanceMode.Incremental)); } else if (cmd.Token is GCSpline) { BoundingBox.AddBoundingBox((cmd.Token as GCSpline).GetBoundingBox(emu.Plane, new double[] { cmd.Start.X, cmd.Start.Y, cmd.Start.Z }, emu.DistanceMode == DistanceMode.Incremental)); } else { BoundingBox.AddPoint(cmd.End); } } BoundingBox.Conclude(); #if DEBUG stopWatch.Stop(); #endif //GCodeParser.Save(@"d:\tokens.xml", Parser.Tokens); //GCodeParser.Save(@"d:\file.nc", GCodeParser.TokensToGCode(Parser.Tokens)); FileChanged?.Invoke(filename); } }