Access SketchUp SDK from C#/ .net project

Please forgive me for waking up this old topic, but I happen to be working on just such a wrapper lately and would be glad to have others involved.

Regarding this bit of code:

I think the best attribute for passing a string to the C API might be LPUTF8Str, as this is the form the documentation says functions taking strings as input expect. For a lot of us, it won’t make any difference, as strings encoded in ASCII match their own UTF-8 encodings. But it doesn’t work the other way. That is, telling the marhsaller to convert a C# unicode string to LPStr encoding might lose characters that are ouside the ASCII subset. (This means you can leave the MarshalAs attribute out entirely, if you know your strings can always be represented correctly in the ASCII subset, but better to leave it in.)

Also, the In attribute is optional. The marshaller does a pretty good job of inferring that kind of thing from our uses of ref and out.

Here’s a variation on kengey’s wrapper:

using System;
using System.Runtime.InteropServices;

namespace YourNamespace
{
    public static class API
    {
        const string LIB = "SketchUpAPI";

        [DllImport(LIB, EntryPoint = "SUInitialize")]
        public static extern void SUInitialize();

        [DllImport(LIB, EntryPoint = "SUTerminate")]
        public static extern void SUTerminate();

        [DllImport(LIB, EntryPoint = "SUModelCreateFromFile")]
        public static extern SUResult SUModelCreateFromFile(
            ref IntPtr model,
            [MarshalAs(UnmanagedType.LPUTF8Str)]
            string file_path);
    }
}

Note that API can be a static class,and that the Attribute suffix of an attribute name is also optional.

I’d be very curious to know interested folks’ thoughts on these versions, and whether anyone sees any other issues in either of them.

1 Like

Yes, it could have been less complicated.
Over the years I have wrapped the sdk more than once in C#, but I never really got to using it in production. In the end I always went for native.

1 Like

It certainly can get tedious, wrapper after wrapper. I programmed in C for years, avoiding managed languages because they seemed slow and burdened with safety nets and training wheels that “real” programmers didn’t need. Today, I am completely on board with C#. In those rare (but not unheard of) cases where you need it, unsafe code provides the few things left in C I might miss. And all the tricks and magic the compiler writers and CPU designers have developed seem to have made any remaining performance issues almost vanish.

I worked in Java for a while, but its approach to calling native functions is a mess. You have no choice but to write original code in the native language, which not every programmer is even going to know. C# lets you write your wrappers entirely in C#. You do need to know about about memory layout and so on, but that’s a far cry from having to learn C.

So, my objective is to create a wrapper that is all C#. The other efforts I’ve seen use C++. That’s fine, but it means potential contributors who only know C# can’t help you. Now, as you clearly know, wrapping the entire C API is a big effort. I wanted something that would, at first, let me create models that I can import into Unity. Unity relies solely on C# as its programming language, so this seemed like the natural choice. So far, I’ve wrapped everything I need to create faces, components, groups, instances, and map them with materials. I can read and write those parts of a SketchUp file. Just to get that far, I’ve had to wrap 130 functions/structures.

To avoid having to deal with a lot of the nitty-gritty (counting vertex numbers, etc.) while creating models, I’ve written a companion library that lets me read a SketchUp model, then operate on it using a simplified document model that supports the features one needs for Unity models, then write it out to another SketchUp file for import into Unity. Basically, it is (yet another) import/export tool, but to and from a very simple document model.

If anyone reading this is interested in seeing what I’ve got, let me know! I’d be delighted to have others involved in it.

Cheers!

I looked at it, and so far what you show (in this repo) is not an API. You have a C# binding for the SketchUp C API. It (currently) still requires doing and accessing things in the clunky C way that some of us hate.

This is what I’d really be interested in, and true OOP API.

C# is a object oriented language that is C-like ( ie, C.O.O.L :wink: ) and us OOP geeks love Ruby (or Python) and like JavaScript, but wished it was compilable into executable or dynamic library files.
We’ve gotten spoiled with the weakly typed references that don’t need to be declared, and can point at any type object at any time or be changed to point at differently typed objects at any time during runtime.
But I’m sure most long time coders had to use strongly typed languages in the past (if not just in college,) and we’d likely accept the limitation if it means we can truly compile an app or extension.

But IMO, the object model for a publicly usable API needs to mirror the object model class structure of the Ruby API, (which I’m told mirrors the internal C++ object module as close as it could.)

If it diverges too much from this, those of us who’ve used it for many years (~10 in my case) will not adopt it (or adapt to it if they do,) all that that quickly.

There are also some issues to consider if it is to be an open source community project (be it binding, library or API … whatever the project goal will be.)

Namespace and licensing

  1. You’ve wrapped it your proprietary company namespace.

  2. You’ve declared copyright on it.

  3. You’ve not attached any licensee or terms of use.

  4. There are specific and general clauses in the Trimble API Terms of Service that apply to using their API and wrapping it. Those need to be considered, especially:
    a. Section 2: Your End Users. (The API Terms need to be included.)
    b. Section 3: Ownership.
    c. Section 4: prohibition 1.
    d. Section 6: Attribution.
    e. Section 9: Liability (Disclaimers & Limitations need to be stated.)

Maintenance

  1. Every single C API function is wrapped in a separate .cs file.
    It is not just tedious to browse through. It may be likely that namespace names will change. I’d not wish to do this for every file manually. (Notepad++ can search and replace across files following a project folder structure and filtering for certain filetypes, like as .cs files. I’d think VS should also have this ability.)
    But for those familiar with the SketchUp API and it’s files, I’d (think) we’d prefer to be able to use it’s file naming structure for any binding or API wrapping. I’d want to open the "bindings/model/model.cs" file and see the C# binding wrappers for ALL of the SUModelRef object.
    http://extensions.sketchup.com/developer_center/sketchup_c_api/sketchup/files.html

  2. There is also work being done on the ability to use the C API on a “live” model. (Currently it is only safe to do readonly C API calls on a “live” model loaded into the SketchUp application proper.) There are 2 different libraries that need to be loaded (linked to) depending upon if the use is external or internal to the SketchUp application. (There are also a few functions that are only exported by the application itself.)
    So anyway, it would be good if there was a way to decide which when it comes to specifying the API import library.

  3. Examples - It seems weird that examples for other people are wrapped in the same namespace as the API.
    I’d think other coders will have their own namespace(s) and I’d hope that they would “import” the API with a “using” statement. Yes / No? If so examples should reflect actual use (and possibly serve as a template that coders can change the namespace identifiers to suit.

    using SketchUp.API
    
    namespace SomeCompany.SomeCertainPlugin {
    
        /// Code the uses the SketchUp API
    
    }
    

A few years ago I started working on a “real” c# api that was OO. So there was a Model class that had properties and functions, just like the ruby api has. I never worked on it profoundly because… well… other work had to be done.

Let me try to setup a github repo during the day, and if I don’t, please help me remember doing so.

Or @thomthom, maybe a repo could be setup on sketchup’s github?

1 Like

I have a legal question about this. Since the wrapper needs the sdk binaries I was wondering if it is allowed to make these binaries part of the public repo?

Since the binaries are currently behind a login-wall - lets hold off on this for a bit.

We have an old copy of your wrapper and a Trimble wrapper in a private repo. We’ve not had time to work on it.

I’ve yet to have a look at Steven’s approach to this.

But there clearly is an interest and need for this.

Tommy started a C++ wrapper which has made progress:

Being maintained by the community it probably would work well for a community driven C# wrapper as well. But we have a few different solutions started.

Maybe we can do a breakout session at DevCamp in Leeds?

Personally I also have a C++ wrapper on top of the Ruby API that would be nice to open source. Maybe we can plan some time for Q4 this year for us (SketchUp) to aid in getting these wrappers out there.

2 Likes

Sounds good. Let’s reopen this discussion in a few weeks in Leeds.

1 Like

Wow! Thanks for the detailed review, Dan.

Correct. It’s a wrapper. As a basic building block, I want to have as many C API functions wrapped as possible (ideally, all of them, though that’s a lot of work, and many are unnecessary for Unity developers). By starting with a transliteral implementation, nothing gets left out. After that, all further work can be done in C#, without having to worry about anything specific to C or even P/Invoke.

I see your point. I’m not (yet) familiar with the Ruby API. My design is driven by what a Unity gamedev would need. It does mimic the SketchUp document model, but it’s not married to it. I’ve got it close to ready for you to look at. Will probably be able to open it up this week.

Yes, as per “Elements of C# Style” R.3.11. I’m open to suggestions for other conventions, though.

Not explicitly. It’s actually pretty hard not to have copyrights under the Berne Convention, though you can transfer/sell them. Of course, Trimble has copyrights to its own material. I’d be grateful for your recommendations on this too.

Will do that before making it public. Would like to have Trimble’s okay on my choice and on making the project public overall.

That TOS appears directed at using an online API (consider “monitoring,” for example), but it is the one they link to from the C API documentation, so I take it as applicable. I believe I am (or will be) in compliance with its terms, but would ask for Trimble’s review/blessing.

Correct. They are named one-for-one for the functions they wrap, so finding any particular one would be easy. Since, with very few exceptions, they are transliteral, there would be little reason for anyone using them to want to see the source. But each function is easy to find because the names match. It wouldn’t be a big deal to gather the up into groups that match what’s in the various .h files in the C API, though. If there’s a call for that, I’d be happy to do it.

Agreed.

They actually are in different namespaces, but there’s no using statement because the projects are in the same solution. You’re right, though. The examples should be as much like end-user code as they can be. I’ll break them out into a wholly isolated solution.

EDIT: You’re right! I’ll change it. And thanks for helping me learn something I didn’t know about C# namespaces.

That is absolutely awesome feedback, Dan, and fast, too. Many thanks!

Stevens

I wondered about that too. It appears that a number of public github repos already do this:

Unity’s PiXYZWorkShop

Tommy Kaneko’s wrapper.

Another wrapper.

Because the TOS appears written with a Web API in mind, it’s kind of vague about this. The Developer Center Guidelines do address it, in a general way:

But, no need to play cute on a clear question. We should simply ask Trimble for permission and see what they say or what conditions they want to impose.

1 Like

I’m afraid I won’t be in Leeds (I’m in Virginia, USA). But I would like to keep working on this. What do you all recommend? (Kenny, I know you haven’t seen my repo yet, but it is essentially the same, wrapper-by-wrapper, as the C# snippets you and I already posted here. Shortly, I’ll have a higher-level API to post as well, which I’d be glad to have you inspect along with Dan and Thom.)

1 Like

"/CsharpSketchUpAPI/blob/master/CsharpSketchUpAPI/Properties/AssemblyInfo.cs"

… looked explicit to me … ie:

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("CsharpSketchUpAPI")]
[assembly: AssemblyDescription("A C# wrapper for the SketchUp C API")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Ex Lumina Corporation")]
[assembly: AssemblyProduct("CsharpSketchUpAPI")]
[assembly: AssemblyCopyright("Copyright ©  2019")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

And I believe you can make an explicit statement of no copyright, releasing to the public domain.

You can also have open source licenses (MIT, etc.) that has copyrights of each successive contributor and the license forbids the removal of these copyright statements.

It is also included within the download archive of the C API’s SDK. It is also linked from the Ruby API documentation pages.

There is (I think) an additional legal agreement document for registered developers (which applies in addition to the publicly posted terms.)


I think I’ve been through this question before with Thomas in a private thread.

We have this “informal” statement …

The C SDK “Main Page” specifically says …

The C API library for Windows is built using Microsoft Visual Studio 2015 SP1 (v140). It includes only 64-bit binaries. Building and releasing an application using the SketchUp C API for Windows requires including SketchUpAPI.dll and SketchUpCommonPreferences.dll, which can be found in the SketchUp C SDK for Windows. Also, the following C runtime DLLs must be included: msvcp140.dll and msvcr140.dll. Alternatively the Microsoft Visual C++ 2015 SP1 Redistributable Packages can be used(gives MS download link.)

But not a good legalese statement of permission to distribute.

Heh. I didn’t copyright it. Microsoft did. That’s machine-generated code. But, even if I take it out, I still have a copyright in it. You have a copyright in anything you create once it is “fixed in a tangible medium.”

I researched this while I was in law school. It’s a widely recognized, somewhat puzzling omission in the international conventions that govern copyrights. It used to be the case that you had to put a copyright notice on things. If you didn’t, they were public domain. When the Berne Convention adopted the “fixed in a tangible medium” standard, copyrights attached automatically. But no one bothered to consider the case where a person might be willing to abandon those rights. If you did put an “I abandon my copyrights” statement at the top of your code, I expect most judges would ask you to abide by it. But I wouldn’t bet my license on that.

Note that open-source licenses themselves tend to assert copyrights. Without that, you can’t enforce the terms of the license.

I actually would be willing to put my faith in that, but the question Kenny asked was about publishing them to public repos. That’s very slightly different, since it makes them readily available to anyone for download on their own. In a distributable product, they’d be somewhat obscured. (Any tech-savvy user could find them, but not everyone.) Regardless, the requirement would probably be there that we have to prohibit redistribution of Trimble’s file(s). Developers can distribute them (assuming that informal statement you’ve quoted is binding, which I think it is), but people not licensed by Trimble to be developers can’t.

However, like I said above, I think the right thing to do will be to ask Trimble for a review and get their blessing. I’m hoping Thom can point me towards the right people when we reach that point.

Still working on the higher-level stuff. Will have that ready to show you in a couple of days.

Thanks again!

And runs the risk of falling behind version-wise, if the repo owner doesn’t keep up with things.

I toyed with the idea of Trimble releasing a redistributable kit (like Microsoft does,) for specific runtime API support. (But the users of other 3rd party applications might install it when the application is not compatible with the version installed. I guess this is why these are distributed by the application developers.)

So I think anyone using the C# API would (and should) get the latest version release of the C API and install it alongside (sibling folders) of the C# API.

See more explanation in Issue #1 of Steve’s C# repo, for those with access and C# project know how.

I think this would be best. As a Trimble endorsed and moderated community SDK project.

This way there’d be no legal issues.

Also the main thing I’ve over the years, is that developers just will not put their trust in 3rd party libraries in order to develop extensions. They want “official” libraries that they can rely upon to be maintained, fixed, updated and expanded. They have been concerned that these projects will get abandoned.

1 Like

There’s soimething to be said for the repo including the library it is known to run with, but I think your next point actually dominates over that issue.

Yes, this! All issues about keeping current and not breaking any rules are solved this way.

Ah, someone who gets it. As a lawyer, I always tell my clients, “The best time to settle a dispute is before it comes up.” I’m confident that Trimble expects developers to be distributing the C API .dll files for reasons we’ve discussed above. But my confidence is no one else’s license. If we get their approval, all questions are settled in advance. That’s best.

Agreed. It does appear that those of us here in this discussion are fairly enthusiastic about this. If we can cobble up something that looks like it is in Trimble’s interests to endorse, we should be able to overcome this problem exactly as you have outlined. I’d really like to see that happen!

@tt_su and @kengey, I am pretty sure I can’t join you in Leeds (my wife read this discussion and said I should go, but I’m not going to England without her, and she can’t make it in October). If there is a break-out session, can you folks include me and Dan (assuming he’s on this side too) by teleconference?

Well I am not a C guru (but can read it,) and I would like to start using C# and compiling some plugins (perhaps also for other modelers that use C#.)


It’d be better to have just you 3 “C gurus” get your heads together over the implementation.
I’m more of the high level language kinda guy. I’m more interested in the OOP layer than the binding/wrapping part.


But I’ve said what I think an “official” C# API should strive for in the issue in steve’s private repo. I’ll quote that part here …

I don’t have a problem with transliteral named wrapping functions. (This is also done in Ruby when wrapping a FFI with the Fiddle class.)

But the OOP Layer should follow Sketchup OOP API namespace (module), constant, class and method naming convention. Ie, for the OOP “end coder”, the wrapping/binding part of the C# API would be transparent. They should’n ever need to know or care about how the binding to the C API was accomplished. Meaning they’ll never themselves use the SUModelRef identifier. They should interact with a Sketchup.Model C# class instance object.
The doc manual should hide the bindings from the OOP users. (Ie, separate manual for the OOP layer. The bindings possibly in their own namespace. Out of sight - out of mind.)

I’ll add to this, that as a Rubyist, I have a peeve when Ruby conventions are broken (which Ruby allows because it is flexible,) for Ruby libraries or APIs.

BUT, … a C# API is most likley to be implemented using the best practices of the C# language.
This means no SCREAMING_CONSTANTS even though both the C and Ruby APIs use them by convention.

After reading up on C# naming conventions, I remember now why I uninstalled Visual Studio, and decided to get into Ruby instead of any of the MS Visual langauges. All identifiers, for just about everything in these languages is PascalCase.
You cannot tell, at a glance what (kind or type of object) the identifier is referencing. This peeve is one of the things made me fall in love with Ruby. It uses different convention for different kinds of programming objects. Ie, namespaces (ModulesAndClasses), CONSTANTS, method_names, localVars, @instance_vars, @@class_vars, etc.
It is gonna be a bummer relearning my brain to program where almost everything is NamedLikeThis. :frowning:

But, as a realist, I cannot expect an “official” API to purposefully violate the conventions of the language it’s implemented in. (Ignoring the past API transgressions when Ruby conventions were broken. Ie, constants that were implemented in C# / JS PascalCase convention instead of SCREAMING_CAPS, or method names in either PascalCase or camelCase, instead of Ruby’s conventional snake_case.)

If the C# API for SketchUp’s conventions did not reflect industry language conventions for C#, it’d be rejected and ridiculed into disuse.

That might be doable. Virginia, US would be five hours behind UK? If we get something organized it would be at the end of the day, so at least it’d be day-time for you. But maybe in the midst of working hours…?

As for the C API binaries, for the moment I’d say that people should craft their projects such that the user of it plugs in their own version of the C API. It would be a bigger talk internally about bundling n projects like this.
I did something similar for an assimp fork where I was adding .skp file support:


I used their convention of putting the binaries (or symlink) in a contributing folder and the CMake system would pick it up when generating the project. I’ve seen other projects use environment paths.

No problem! I am self-employed, so can join you anytime. That would be great, if we can make it happen.

Well, I think Dan had a good point on that about version compatibility being a risk. I really don’t see how Trimble would think developers can develop anything with these .dll files if we’re not allowed to bundle them with our code. I will talk to Trimble’s legal people about this. Is there anyone in particular you suggest I talk to first?

I have put my OOP layer into a github repo and made it public. Hope you fellows will have a look and let me know what you think.

1 Like