Method not found SpeckleCoreGeometryRevit.Conversions.ToSpeckle


#1

Hi guys,

Sorry for the dumb question. I’m trying to use Speckle in a C# script with Rhino Inside Revit to familiarise with the Speckle components.

I’ve loaded SpeckleCoreGeometryClasses, SpeckleCoreGeometryRevit, SpeckleElements and SpeckleElementsRevit.

When I try to convert a Revit point to a Speckle point I get this error:

  1. Method not found: ‘SpeckleCoreGeometryClasses.SpecklePoint SpeckleCoreGeometryRevit.Conversions.ToSpeckle(Autodesk.Revit.DB.XYZ)’. (line: 89)

I think the method exists so I don’t understand why it cannot be found.

If I copy the ToSpeckle method in the Custom additional code then it works.

Thank you
Giovanni

using System;
using System.Collections;
using System.Collections.Generic;

using Rhino;
using Rhino.Geometry;

using Grasshopper;
using Grasshopper.Kernel;
using Grasshopper.Kernel.Data;
using Grasshopper.Kernel.Types;

using System.IO;
using System.Linq;
using System.Data;
using System.Drawing;
using System.Reflection;
using System.Windows.Forms;
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 SpeckleCoreGeometryClasses;
using SpeckleCoreGeometryRevit;
using SpeckleCore;

using SpeckleElements;
using SpeckleElementsRevit;

using Autodesk.Revit.DB;


/// <summary>
/// This class will be instantiated on demand by the Script component.
/// </summary>
public class Script_Instance : GH_ScriptInstance
{
#region Utility functions
  /// <summary>Print a String to the [Out] Parameter of the Script component.</summary>
  /// <param name="text">String to print.</param>
  private void Print(string text) { /* Implementation hidden. */ }
  /// <summary>Print a formatted String to the [Out] Parameter of the Script component.</summary>
  /// <param name="format">String format.</param>
  /// <param name="args">Formatting parameters.</param>
  private void Print(string format, params object[] args) { /* Implementation hidden. */ }
  /// <summary>Print useful information about an object instance to the [Out] Parameter of the Script component. </summary>
  /// <param name="obj">Object instance to parse.</param>
  private void Reflect(object obj) { /* Implementation hidden. */ }
  /// <summary>Print the signatures of all the overloads of a specific method to the [Out] Parameter of the Script component. </summary>
  /// <param name="obj">Object instance to parse.</param>
  private void Reflect(object obj, string method_name) { /* Implementation hidden. */ }
#endregion

#region Members
  /// <summary>Gets the current Rhino document.</summary>
  private readonly RhinoDoc RhinoDocument;
  /// <summary>Gets the Grasshopper document that owns this script.</summary>
  private readonly GH_Document GrasshopperDocument;
  /// <summary>Gets the Grasshopper script component that owns this script.</summary>
  private readonly IGH_Component Component;
  /// <summary>
  /// Gets the current iteration count. The first call to RunScript() is associated with Iteration==0.
  /// Any subsequent call within the same solution will increment the Iteration count.
  /// </summary>
  private readonly int Iteration;
#endregion

  /// <summary>
  /// This procedure contains the user code. Input parameters are provided as regular arguments,
  /// Output parameters as ref arguments. You don't have to assign output parameters,
  /// they will have a default value.
  /// </summary>
  private void RunScript(object x, object y, ref object A)
  {

    //var spkShaft = new SpeckleElements.Shaft();
    
    XYZ revitPt = new XYZ(50, 32, 45);
    
    SpecklePoint spePt = SpeckleCoreGeometryRevit.Conversions.ToSpeckle(revitPt);
    
    SpecklePoint spePta = ToSpeckle(revitPt);
    
    A = spePt;
  }

  // <Custom additional code> 
  public static SpecklePoint ToSpeckle(Autodesk.Revit.DB.XYZ pt)
  {
    double Scale = 1;
    return new SpecklePoint(pt.X / Scale, pt.Y / Scale, pt.Z / Scale, null, null);
  }
  // </Custom additional code> 
}

#2

Hello @GiovanniB! Off the top of my head, so please bear with me!

Point the first: The conversion routines are static extension methods, so they should be called like:

revitPt.ToSpeckle();

Point the second: You might need to reference the SpeckleCore.dll too (actually you do!), but to ensure the kits are loaded in the appdomain (bla bla bla) you need to call

SpeckleCore.SpeckleInitializer.Initialize();

before you do anything, to ensure that the extension methods are loaded up from the kits. Sometimes the CLR does strange things, and this should force things to go the right way.

Point the third: Depending on wether SpeckleCore.dll was built for debug or release, it will look for the kits in %localappdata%/SpeckleKitsDebug (debug) or %localappdata%/SpeckleKits (release). Take care with this, especially if on a machine that you installed the plugins via the installer and debugging and building your own thing too.

Finally, to convert things, you might just want to go this way:


// first, initalise things
SpeckleCore.SpeckleInitializer.Initialize();

var myRevitPoint = new XYZ( 0, 1, 42 );

// the converter serialise and deserialise functions are rather lenient, and 
// should do the reflection for you, and match the correct conversion routines 
// with their correct types, if present.
var mySpecklePoint = (SpecklePoint) SpeckleCore.Converter.Serialise( myRevitPoint );

// nevertheless, in revit i sometimes get errors if the dynamo conversion routines
// are also loaded up, so we need to exclude things with dynamo in their names, in
// which case you call it like this:
var mySpecklePoint = (SpecklePoint) SpeckleCore.Converter.Serialise( myRevitPoint, new string[] { "dynamo" } );

Let’s see if this gets you anywhere :slight_smile: I’m slightly suspicious of how assembly loading will work with rhino in revit etc, but it should be ok in theory…


#3

Thank you again Dimitrie.

Calling the SpeckleInitializer and tidying up the namespaces worked!