using System.Linq;
private void RunScript(Mesh mesh, ref object A)
{ Component.Name = "Face.Edge Boundaries by unweld Edge";
var ix = System.Linq.Enumerable.Range(0, mesh.Faces.QuadCount * 4 + mesh.Faces.TriangleCount * 3);
var edges = new List<Polyline>();
mesh.UnweldEdge(ix, true);
var meshf = mesh.ExplodeAtUnweldedEdges();
foreach(var m in meshf){
var v = m.Vertices.ToPoint3dArray().ToList();
edges.Add(new Polyline(v));}
A = edges; }
hi @AndersDeleuran Thanks-
i Convert it to c# and use 2 method and using{ System.Parallel cpu Core} and imporoved ;but grasshopper component is faster- Is it really possible to write a code that is faster than that?
using System.IO;
using System.Linq;
using System.Data;
using System.Drawing;
using System.Reflection;
using System.Windows;
using System.Xml;
using System.Xml.Linq;
using System.Runtime.InteropServices;
using Rhino.DocObjects;
using Rhino.Collections;
using GH_IO;
using GH_IO.Serialization;
using System.Security.Policy;
using Rhino.Runtime;
using System.Security.Cryptography;
using System.ComponentModel;
using System.Threading.Tasks;
using System.Collections.Concurrent;
private void RunScript(Mesh mesh, ref object A)
{
Component.Name = "Face.Edge by unweld Edge Parallel.";
var edges = new ConcurrentBag<Polyline>();
var vts = new List<Point3d>();
// foreach(Rhino.Geometry.MeshFace f in mesh.Faces){
System.Threading.Tasks.Parallel.ForEach(mesh.Faces, f => {
var pa = mesh.Vertices.Point3dAt(f.A);
var pb = mesh.Vertices.Point3dAt(f.B);
var pc = mesh.Vertices.Point3dAt(f.C);
if( f.IsQuad)
{ var pd = mesh.Vertices.Point3dAt(f.D);
vts = new List<Point3d>(){pa,pb,pc,pd};}
else
vts = new List<Point3d>(){pa,pb,pc};
edges.Add(new Polyline(vts));});
A = edges;
}
The primary penalty is likely outputting the polylines. If you wrap them in Grasshopper.Kernel.Types.GH_Curve you should see a substantial performance boost. And you need to compile the component to really see the benefit of writing this in C#. Here’s going to 1000 with the GHPython example I posted, it’s slightly faster in SDK mode. I would expect a non-threaded C# scripting component to at least hit this performance:
Firstly, if you want to use a parallel loop, it’s better to use a simple array instead of a fancy “ConcurrentBag.” This is because we already know exactly how many faces there are, so the ConcurrentBag isn’t needed.
In this situation, using a parallel loop won’t make things much faster because there’s not a lot of work to do in each step.
As @AndersDeleuran mentioned, you can make things quicker by changing the output to the standard Grasshopper type called “GH_Curve.”
@Mahdiyar
Thanks
If we generate this code in visual studio using new GH_Curve(pl) is effective for improvements speed of components or not only in c# grasshopper Component?
Assuming this means compiling the component, then yes that should improve performance. See this post on the old forum for a great example:
And while we’re micro-optimising, I’ve noticed that the method by which we get mesh faces affects performance too. Where in GHPython at least, a for each loop is fastest:
Hi @AndersDeleuran and @Mahdiyar Again
I tried to create the Inset Mesh C# component but the Weaverbird image frame component is much faster than Comonent I use Gh_Mesh for faster - do you have any suggestions to optimize thisWeaverbird codebetter? inset mesh faster.gh (8.4 KB)
private void RunScript(Mesh mesh, double dist, ref object M)
{
Component.Name = "Inset Mesh";
var pl = Boundary.MeshToPoly(mesh);
var msh = new Mesh();
var m = new Mesh();
// Parallel.ForEach(pl, p =>
foreach(var p in pl)
{var ver = new List<Point3d>();
var cen = p.CenterPoint();
var t = Transform.Scale(cen, dist);
var dup = p.Duplicate();
dup.Transform(t);
for (int i = 0; i < p.SegmentCount; i++)
{msh = new Mesh();
ver = new List<Point3d>
{p.SegmentAt(i).PointAt(0),
p.SegmentAt(i).PointAt(1),
dup.SegmentAt(i).PointAt(1),
dup.SegmentAt(i).PointAt(0)
};
msh.Vertices.AddVertices(ver);
msh.Faces.AddFace(0, 1, 2, 3);
m.Append(msh);
}
}
// );
m.Weld(0);
var mm = new GH_Mesh(m);
M = mm;
}
// <Custom additional code>
public static class Boundary
{
public static List<Polyline> MeshToPoly(Mesh mesh)
{
// var edges = new ConcurrentBag<Polyline>();
var edges = new List<Polyline>();
// Parallel.For(0, mesh.Faces.Count, i =>
for (int i = 0; i < mesh.Faces.Count; i++)
{
var f = mesh.Faces[i];
Polyline pl;
if (f.IsQuad)
{
pl = new Polyline(new[]
{
mesh.Vertices.Point3dAt(f.A),
mesh.Vertices.Point3dAt(f.B),
mesh.Vertices.Point3dAt(f.C),
mesh.Vertices.Point3dAt(f.D),
mesh.Vertices.Point3dAt(f.A)
});
}
else
{
pl = new Polyline(new[]
{
mesh.Vertices.Point3dAt(f.A),
mesh.Vertices.Point3dAt(f.B),
mesh.Vertices.Point3dAt(f.C),
mesh.Vertices.Point3dAt(f.A)
});
}
edges.Add(pl);
}
//);
return edges.ToList();
}
}
If you are going to replicate/study existing components, you can decompile the relevant .dll using DNSpy or ILSpy to read the source code. This is technically a breach of license, but as far as I gather is not frowned upon too hard around here.
Is there any link of this ?(i don’t find any opensource of this plugin in web or github) maybe not opensource?
I need know mechanism it to use a generete complex code for subd and better bases code is fast and optimized
If you are located in the European Union, any form of de-compilation or disassembling binaries is allowed by law, if you follow the purpose of interoperability. No matter what a license says. You also don’t need to ask McNeel for doing so:
However, if you plan to copy and paste code, and then republish the code, then this another thing. However, I’m not so sure that the complexity involved satisfies a copyright issue. Because Grasshopper components usually only call the Rhinocommon library in a specific way. So you see its a grey area. I would be very careful with copy and pasting code and republishing it.
Btw, ILSpy is used in Visual Studio as the default decompiler…
But a standalone version you find here: