@zhangvip0755 wrote:
For example, “reparameterize” conversion of surfaces and curves.
Thanks in advance!
Posts: 2
Participants: 2
@zhangvip0755 wrote:
For example, “reparameterize” conversion of surfaces and curves.
Thanks in advance!
Posts: 2
Participants: 2
@rawitscher-torres wrote:
Hi guys,
I am having a rather confusing moment here… which its kind of annoying because logically I don’t understand the reason of why its happening.
Here is what I am trying to do:
Loop through a
List<object>
check the type of each item, if the type of an item equals my specified type I will add it to a list. This works perfectly in a C# component but In Visual Studio it always evaluates to false. I am inputting that list under thepManager.AddGenericParameter()
in VS.Here is the code I used to test the same logic in a C# component:
List<object> junk = new List<object>(); junk.Add(1.0); junk.Add(SharpColor.Zero()); junk.Add("hi"); List<SharpColor> dataValues = new List<SharpColor>(); for (int i = 0; i < junk.Count; i++) { if (junk[i].GetType() == typeof(SharpColor)) { dataValues.Add((SharpColor) junk[i]); } } A = dataValues;
Here is the actual code in visual studio ( omitted some details for simplicity)
protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager) { pManager.AddGenericParameter("Values", "V", "Values", GH_ParamAccess.list); } /// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { #region GATHER INPUT DATA List<object> _dataValuesTemp = new List<object>(); DA.GetDataList(5, _dataValuesTemp); #endregion #region INITIALIZE DATA CLASS // Create Data object if (_dimension.EnvironmentDimension == EnvironmentDimension.Environment3D) { switch (m_dataCategory) { case DataCategory.DifussionValues: { if (_reset) { List<SharpColor> dataValues = new List<SharpColor>(); for (int i = 0; i < _dataValuesTemp.Count; i++) { //**************************** Always evaluates to false! if (_dataValuesTemp[i].GetType() == typeof(SharpColor)) { dataValues.Add( (SharpColor)_dataValuesTemp[i] ); } //**************************** Always evaluates to false! } Data<SharpColor> m_Data = new GenerativeFloorPlans.Data.Data<SharpColor>(_xDim, _yDim, _zDim, m_dataCategory, dataValues); DA.SetData(0, new GH_ObjectWrapper(m_Data)); } break; } } } #endregion }
Does anyone have any idea why this is happening? @DavidRutten do you have any insights? does it have to do with how the
pManager.AddGenericParameter()
is defined?Thanks!
Posts: 3
Participants: 2
@daniel.depoe wrote:
Hello,
I have written a very simple C# node to test a line length then divide with points based on results. When I plug in multiple lines and try to pass through a stream filter it’s failing.
Am I missing a graft? Or is something more required in the C# node?
See attached.
Thanks,
Dan
test.in.bounds.divide.gh (9.2 KB)
Posts: 4
Participants: 2
@Baris wrote:
Hi evereyone,
I am trying to planarize some QuadMeshFaces within a loop.
I found this thread here
: https://www.grasshopper3d.com/forum/topics/vb-planar-mesh?page=1&commentId=2985220%3AComment%3A1434649&x=1#2985220Comment1434649
and started to write what @Dani_Abalde proposed:ErrorGlobal as new double
Count as new integer
Do
A tree that stores, for each vertex, a list of vectors.
Per face:
Plane from point cloud.
For each point of the face:
Projecting the point to the plane and the distance is the factor error. You need to know if the value is positive or negative.
Add the vector (vertex - Project vertex) to the tree. the branch is the index of the vertice.
End
Per vertex:
Making the average of the vectors in the respective branch in the tree.
Move the vertex of the mesh with the average vector.
errorglobal += vector length
End
errorglobal / = vertices.count 'Average error or another way to see.
count + = 1
Loop while errorglobal> 0.01 or count <1000My attempt so far:
private void RunScript(Mesh msh, ref object vertices, ref object planes, ref object distances, ref object averageVec, ref object moveVector, ref object Mesh, ref object cnt) { int count = 0; for (int co = 0; count < 20 ; co++) { var verticesTree = new DataTree<Point3d>(); var distancesTree = new DataTree<double>(); var moveVectorTree = new DataTree<Vector3d>(); var planesTree = new DataTree<Plane>(); var averageVectorTree = new DataTree<Vector3d>(); //Per face_____________________________________________ for (int i = 0; i < msh.Faces.Count; i++) { //getting the vertices and putting them in a tree Point3f a; Point3f b; Point3f c; Point3f d; msh.Faces.GetFaceVertices(i, out a, out b, out c, out d); verticesTree.Add(a, new GH_Path(i)); verticesTree.Add(b, new GH_Path(i)); verticesTree.Add(c, new GH_Path(i)); verticesTree.Add(d, new GH_Path(i)); } for (int i = 0; i < verticesTree.BranchCount; i++) { // projecting vertices to plane to get vectors and distances Plane plane; PlaneFitResult pFit = Plane.FitPlaneToPoints(verticesTree.Branch(i), out plane); planesTree.Add(plane, new GH_Path(i)); for (int j = 0; j < verticesTree.Branch(i).Count; j++) { Point3d copy = verticesTree.Branch(i)[j]; Transform xForm = Transform.PlanarProjection(plane); copy.Transform(xForm); double dis = copy.DistanceTo(verticesTree.Branch(i)[j]); distancesTree.Add(dis, new GH_Path(i)); Vector3d move = (verticesTree.Branch(i)[j] - copy); moveVectorTree.Add(move, new GH_Path(i)); } } //per vertex___________________________________________ for (int i = 0; i < verticesTree.BranchCount; i++) { for (int j = 0; j < verticesTree.Branch(i).Count; j++) { Vector3d averageVector = average(moveVectorTree.Branch(i)); averageVectorTree.Add(averageVector, new GH_Path(i)); Transform xForm = Transform.Translation(averageVector); verticesTree.Branch(i)[j].Transform(xForm); } } count += 1; vertices = verticesTree; planes = planesTree; distances = distancesTree; averageVec = averageVectorTree; moveVector = moveVectorTree; cnt = count; } } // <Custom additional code> //_________Making an average Vector public Vector3d average (List<Vector3d> vectors) { Vector3d avg = new Vector3d(0, 0, 0); for (int i = 0; i < vectors.Count; i++) avg += vectors[i]; return avg / vectors.Count; }
My issues:
- the average vector that I get is always (0,0,0)
- do I have to build the mesh afterwards or can I just move the vertices of the existing one
I hope it´s makes a little bit of sense and is not completly chaotic and far away from a working code.
Thanks in advace !
20191126_PQM.gh (6.9 KB)
Posts: 1
Participants: 1
@Big_G wrote:
Hi All,
Firstly, apologies for the lengthy post.
Can anyone please help me trouble shoot why the objects are not rendered correctly in the Viewport. See image below. The faces look dodgy, some are transparent and some not.
I have followed this example from @DavidRutten Custom Data Type : GH_GeometricGoo or GH_Goo ? . David coded up a Boat.cs example.
My understanding of the workflow and approach was:
public class Column
- (This is my Custom Object Class)
public class GH_Column : GH_GeometricGoo<Column>, IGH_PreviewData
- (Custom Class Goo wrapper)
public class ColumnParameter : GH_PersistentGeometryParam<GH_Column>, IGH_PreviewObject
- (Custom Class Parameter)
public class ColumnComponent : GH_Component
- (The Component)I have implemented the CastTo, CastFrom, DrawViewportMeshes, DrawViewportWires etc. Basically all requirements as per the absatract classes and Interfaces above.
All compiles well. The component work as intended. I have scrutinised the object. All good.
Code extract from GH_Column
public BoundingBox ClippingBox { get { return Boundingbox; } } public void DrawViewportMeshes(GH_PreviewMeshArgs args) { if (Value == null) { return; } if (Value.ColumnBrep != null) { args.Pipeline.DrawBrepShaded(Value.ColumnBrep, args.Material); } } public void DrawViewportWires(GH_PreviewWireArgs args) { if (Value == null) { return; } if (Value.ColumnBrep != null) { args.Pipeline.DrawBrepWires(Value.ColumnBrep, args.Color, -1); } }
Code Extract from ColumnParameter
public BoundingBox ClippingBox { get { return Preview_ComputeClippingBox(); } } public void DrawViewportMeshes(IGH_PreviewArgs args) { Preview_DrawMeshes(args); } public void DrawViewportWires(IGH_PreviewArgs args) { Preview_DrawWires(args); } public bool IsPreviewCapable { get { return true; } }
What is to go with the Preview Methods? Why is this not working? Is this a BoundingBox issue?
Happy to share code, just not sure what part as there is a lot of it.
Posts: 3
Participants: 2
@joy.architect wrote:
Can someone please guide me the setting from where I can change the gh sdk version when building a gh plugin from visual studio?
Lower rhino 6 sr versions are failing to run the exported plugin for the obvious use of latest sdk version. Any external link shall be helpful too.
Thanks!
Posts: 1
Participants: 1
@Moonpick wrote:
Hi,
short easy question:
is it possible to make in a C# script an input parameter optional? In other words, is there by scripting an equivalent to:pManager[1].Optional = true;
which we use in VS writing a plugin?
Posts: 3
Participants: 2
@duanemclemore wrote:
Hi All,
I am developing a component, but am still new to C#. We can get in to the specific code of my question a little later, but let me explain my purpose first and there may be a general answer.
I am trying to generate lattices of 3d points. The eventual goal is to generate very large lattices, so I am trying to use the fastest calculation methods I can. One of my requirements is to be able to select or describe the position of any single item within this lattice as minimally as possible. A one-dimensional array with three elements for each point would be ideal, with an element for the x, y, and z position within the lattice.
I have had no problems using simple nested for loops to generate the x,y, and z indices as separate lists. However, I’ve tried everything I possibly could to get an array out, to no avail.
The VS build is always successful, but when I get to the Grasshopper canvas, there’s usually an error that it could not convert from int32
[]
to GH_Integer.I’ve also tried to build Data Trees using the same loops, unsuccessfully.
I’ve gotten output that Grasshopper will actually recognize from using a one-dimensional Rhino.Geometry.Matrix. However, it never recognizes the looping and only outputs one matrix with the largest index in each direction in that column. And I’m also afraid that since that’s a “geometry” type, it will increase the calculation time once I’m up into the very, very many lattice points.
And on the note of a matrix, a single 3d matrix would be a swell way to describe the lattice point positions, but I fear that it would be the most time consuming addressing method possible.
Anyway - that’s the whole background. If anyone has a way to solve my int32
[]
to GH_Integer problem, that would solve it in a way I could move on with. But if you all need more code to understand what’s actually going wrong, we can get into that.Thanks in advance for any help!
Duane
Posts: 4
Participants: 2
@Filipe_Brandao wrote:
Hello!
I’m was looking for a way to apply a transformation to all lines in a DataTree. A simple way would be to iterate through all elements in the data tree and apply the transformation, but since the tree might contain different elements counts on each branch, this would be cumbersome. As an alternative I was exploring the AllData() method to get a list and apply the transformation to all elements. The problem is that I want to keep the elements with the Tree structure so I have to rebuild the Tree after the transformation. Is there a simpler way to do this without converting the Tree to List?
I was experimenting this but it doesn’t work.
diagonals.AllData().ForEach(delegate (Line line) { line.Transform(transform); });
Posts: 1
Participants: 1
@Baris wrote:
Hi all,
I am trying to move points in a simple for loop but for some reason it does not work.
If I use the same methode without loop it works.
It has to be a silly error I do, I just cant see it.
Thanks for any hint!
20191130_PtsMove.gh (3.5 KB)
Posts: 10
Participants: 3
@rawitscher-torres wrote:
Hi Guys,
When I change the background color of a slider, it is automatically set back to its original color when the component its connected to expires its solution, and when the slider itself expires its solution ( When a value its changed or when moved)
The component which the slider is connected to is the one responsible for changing the sliders background color.
I have tried the following:
IGH_Param input = (Params.Input[1].Sources[0]); slider = (GH_NumberSlider)input; if (slider != null && programType!=null) { Color c = Color.FromArgb(255, programType.ProgramColor.R, programType.ProgramColor.G, programType.ProgramColor.B); slider.Slider.ControlBackColour = c; slider.Slider.DrawControlBackground = true; slider.Slider.ValueChanged += Slider_ValueChanged; } private void Slider_ValueChanged(object sender, Grasshopper.GUI.Base.GH_SliderEventArgs e) { ExpireSolution(true); }
That works fine except that whenever I start to change the slider value it gets extremely slow and not interactive like it should be.
A very ulgy test that I did was to code a separate C# script component that looks for all the components in the grasshopper doc which take care of the sliders color and then expire their solution one by one. Although this works, its definitely a no, no and I am pretty sure there is a better way to achieve this.
private void RunScript(bool Run, string Name, ref object A) { int count = 0; List<IGH_DocumentObject> components = new List<IGH_DocumentObject>(); foreach (IGH_DocumentObject obj in GrasshopperDocument.Objects) { if(obj.Name == Name) { components.Add(obj); count++; } } foreach (var item in components) { if(Run) item.ExpireSolution(true); } if(count == 0) { Component.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "The specified component does not exist in the canvas!"); } Component.Message = "Expire"; if(Run) Component.ExpireSolution(true); A = components; }
This is the slider background that I am changing…
Thank you and any tips would be very helpful
Posts: 1
Participants: 1
@daniel.depoe wrote:
Hello,
Can someone please explain the rationale behind the ‘plane flipping’ phenomenon show here? I’m sure there is a good reason for this behaviour, I’d just like to be able to predict it happening in the future.
Thanks,
Dan
planes.flip.gh (5.0 KB)
Posts: 4
Participants: 3
@basic wrote:
Hi everyone,
Is it possible to create a cluster component in C# that contains your other components?
Let’s say I have 5 components:
Components 1 to 4 are normal components and component 5 is a cluster that contains components 1 to 4.Is this possible to create?
If yes, where should I look for clues and examples?Thank you.
Posts: 2
Participants: 2
@jameseanderson wrote:
Hi!
I have found a bug in Grasshopper for Rhino 6 for Mac. It is related to assigning shortcuts. The shortcut tool actually doesn’t work. The only way to assign or return to default is to edit the text document outside of grasshopper.
I have attached a video of the glitch in the Grasshopper software. As you can see in the video if I assignment the backspace(back) key on mac to delete every time I try and confirm this it just resets it to empty. Originally I had set it up to be the delete key on the larger numeric keypad from apple. (even though the back key in the software is also the delete key on the MacBook). If i set it to the delete key on the apple keyboard with numeric pad then when i am using my laptop on the go I have to change it back to the ‘back’ key as even though physically they are called the same thing the software sees them as different keys. Maybe if you could integrate them or even allow using multiple keys as shortcuts so i can use both keys to delete that would be awesome.
At the moment due to this error I have to go edit then delete every time I want to delete anything in Grasshopper.
Kind Regards,
James
Posts: 1
Participants: 1
@aleksanderdynarek wrote:
I am creating a custom component in C# in VS to generate a boid system in a field. System will be interactive - boids will affect a pheromone point field.
I have boids working, i have custom class generating point field, but i look for a most efficient way for boids to find its neighbour point in a grid. Since I aim for really large values of boids and point grid, i want to avoid closest point etc.
What would be most efficient way? Rtree? Grid is regular, so maybe math? Any experiences?
Posts: 4
Participants: 2
@Roman_Gorshkov wrote:
Just trying to write a tool to cover flat set of text to create a list of points which elevation is based on text string.
Cant find a way to convert text object to string and to doubles for z values?
Also how can I check if the text is a number or a random text ?I know there are lots of tools already, what to do it myself.
List<Point3d> ptList = new List<Point3d>(); double x; double y; double z; foreach(var guid in textID) { var text = Rhino.RhinoDoc.ActiveDoc.Objects.Find(guid) as Rhino.DocObjects.TextObject; if(text != null) { x = text.TextGeometry.Plane.OriginX; y = text.TextGeometry.Plane.OriginY; z = Convert.ToDouble(ToString(text)); Point3d newPoint = new Point3d(x, y, z); ptList.Add(newPoint); } } points = ptList;
TextToPoint.3dm (3.6 MB) TextToPoint.gh (7.2 KB)
Posts: 16
Participants: 4
@garciadelcastillo wrote:
Hi there!
High-level question: is there any way to access
GH_Goo
types in C# Script components before they get converted to other types on inputs via theScriptVariable
?Description: Probably a silly question, but I am blanking out. I am writing a C# Script component (must be so, cannot be a compiled one) and I want to access the history of transforms for a Transform object using
GH_Transform.CompoundTransforms
(as I guess the native Split component does). If the input type is set to Transform, then I lose that history as a I get the flat 4x4 matrix without the history. If I use a genericobject
:private void RunScript(System.Object T, ref object X) { Print(T.ToString()); GH_Transform xform = T as GH_Transform; if (xform == null) { Print("null"); } else { Print(xform.ToString()); } }
…it stringifies to a Transform, but the cast fails:
My guess here is that the object gets “flattened” to aTransform
as it enters the C# Script, before being further “flattened” to anobject
? Is there any way to access the originalGH_Transform
at this point?Thanks!
Posts: 7
Participants: 4
@nickchen11 wrote:
Hello there,
I wonder what is the best way to catch specific component derived from a exploded cluster in C#? I noticed that .ExplodeCluster method doesnt have a return type. Therefore, I tried to get a list of GUID from the cluster which hasnt been exploded first in order to catch a specific component. However, this approach doesnt seem to work as component GUIDs will be regenerated after a cluster is exploded. (not sure if this is the right way to do.)
Another approach I can think of but Im not quite sure how to do it at the moment is checking the latest components added to the gh document and select the one I need within the list. However, with this approach, I’m not sure how GH defines the latest components added to the document as once a cluster is exploded, there will be many added at the same time.
Does anyone know a solution? Thanks in advance.
Posts: 9
Participants: 3
@jia.yeap wrote:
With python, i amble to write data using python as below.
But, what if i wish to write to store the data in a panel or a data component. If so, how to call internalise data with python to write a new line when reading from it?
Posts: 1
Participants: 1