Beginner dev question c# GetObject

Dear Rhino developers. I am trying to build my first plugin in C# with Visual Studio, on which basically I plan to learn this language and build some usefull tool for me and my team. I am noob here and I am stuck at beginning…

I do not know how to pass results of selection from command class to plugin class. Here is my command code (mostly from template).

public class mytestCommand : Command
{
    public mytestCommand()
    {
        Instance = this;
    }

       public static mytestCommand Instance
    {
        get; private set;
    }

      public override string EnglishName
    {
        get { return "mytestCommand"; }
    }

    protected override Result RunCommand(RhinoDoc doc, RunMode mode)
    {
        var go = new GetObject();
        go.SetCommandPrompt("Select open curves in order");
        go.GeometryAttributeFilter = GeometryAttributeFilter.OpenCurve;
        go.DisablePreSelect();
        go.OneByOnePostSelect = true;
        go.SubObjectSelect = false;
        go.GetMultiple(2, 0);

        if (go.CommandResult() != Result.Success)
        {
            return go.CommandResult();
        }

       public List<Curve> mycurves = go.Objects().Select(obj => obj.Curve()).ToList(); 
       //I get here "The name 'go' does not exist in the current context"

       return Result.Success;
    }
}

I was thinking that word public before curve list variable will allow for reference in plugin class, but I cannot get data from get object operation. I was thinking that later in my plugin class I could use for reference something like:

mytestCommand.mycurves    

Where is my stupidity here?

Inside a function you cannot declare scope visibility like that. You should create your declare your mycurves at the class level. Then you assign to it in your RunCommand implementation.

See field documentation. Review this documentation on classes and structs.

1 Like

Thank you. Works like a charm.

Dear @nathanletwory one more question. I am trying to change guid list to curve list. I have fount that for changing types of lists converter structure can be used. So I try…

    public static Curve GuidtoCurves(Guid id)
    {
        return RhinoDoc.ActiveDoc.Objects.Find(id);
    }

    List<Curve> CurvesList = GuidList.ConvertAll(new Converter<Guid, Curve>(GuidtoCurves));

… and no, conversion method is returning object type, not curve type, which breakes further code. This type checking can give a real headache… How I can return curve type, based on guid? Maybe there is easier way to convert list from Guid to Curve?

Also is it safe to use ActiveDoc? VS comment screams “dont use it if you dont have to”.

Your problem is a misunderstanding of the basics on what is a curve, a guid and how type conversion works.

In short: inside the Rhino Doc, a guid is used to identify any Rhino Object. A Rhino Object has a geometry. This geometry can be of type curve. What you have to do is get the geometry of the Rhino Object(which you can find in the doc via guid), check if it’s a curve and then add it to your list.

Also, it is not advised to use RhinoDoc.ActiveDoc if you have the current doc, which you have if you run your code inside a command, it is adviced to use this instead of the former.

this should work, but lacks an important check. But thats something for you to figure out :wink:

public static Curve GetCurveFromGuid(Guid guid)
{
            RhinoObject rhObj = RhinoDoc.ActiveDoc.Objects.Find(guid);

            if (rhObj.Geometry is Curve crv)
                return crv;
            else
                return null;
 }

public static List<Curve> ConvertGuidsToCurves(List<Guid> guids, RhinoDoc doc) => 
guids.ConvertAll(new Converter<Guid, Curve>(GetCurveFromGuid));
1 Like

Dear @roger, thank you for your tips. You are right I am still learning structure of rhino objects and generally c#.

Your tips allowed me to succed with code as below:

public static Curve GetCurveFromGuid(Guid guid)
{
	RhinoObject rhObj = RhinoDoc.ActiveDoc.Objects.Find(guid)
	
	if (rhObj.Geometry is Curve)
	{
		return rhObj.Geometry as Curve;
	}
	else
	{
		return null;
	}
}

List<Curve> CurvesList = GuidList.ConvertAll(new Converter<Guid, Curve>(GetCurveFromGuid));

Hello,
I put you on the track of “Linq”

using System.Linq;
var CurvesList = (from guid in GuidList
                  let crv = doc.Objects.Find (guid) as Rhino.DocObjects.CurveObject
                  where crv != null
                  select crv.CurveGeometry).ToList ();
2 Likes

btw I think ConvertAll is unecessary, as you have to return an item in your convert method, thus returning nulls if your geometry is not a curve. below an example without, using a simple method and foreach loop to do the job without adding a null to your list at all.

public static List<Curve> GetCurvesFromGuids(List<Guid> guids, RhinoDoc doc)
{
        List<Curve> returnCrvs = new List<Curve>();

        foreach(Guid guid in guids)
        {
	    RhinoObject rhObj = doc.Objects.Find(guid)
	
	    if (rhObj.Geometry is Curve crv)
                returnCurvs.Add(crv);
        }
        
        return returnCrvs;
}

List<Curve> CurvesList = GetCurvesFromGuids(GuidList, doc);
1 Like