How to start using HSMWorks API

How to start using HSMWorks API

Anonymous
Not applicable
3,609 Views
15 Replies
Message 1 of 16

How to start using HSMWorks API

Anonymous
Not applicable

Hello,

 

I will start using HSMWorks API in my VB.NET add-in and I would like to ask a very simple question. I hope you guys can help me.

 

The sample API instruction text file located in C:\Program Files\HSMWorks\api\include\AddinAPI.h says the following:

 

To use the HSMWorks API either:

 

1. Link against hsmsw.lib included with the installation in the API folder.

2. Alternatively import the functions at runtime using GetProcAddress():

typedef unsigned int (*HSMWorks_getVersionFunction)(unsigned int* major, unsigned int* minor, unsigned int* micro, unsigned int* build);

HMODULE module = LoadLibrary(L"hsmsw.dll");
if (module) {
HSMWorks_getVersionFunction HSMWorks_getVersion = (HSMWorks_getVersionFunction)GetProcAddress(module, "HSMWorks_getVersion");
if (HSMWorks_getVersion) {
unsigned int major = 0;
unsigned int minor = 0;
unsigned int micro = 0;
unsigned int build = 0;
HSMWorks_getVersion(&major, &minor, &micro, &build);
}
}

 

I guess the given code is for C++. My add-in is in VB.NET. What should I add to my code instead?

Or let's consider the first option above. It says that I should "link against hsmsw.lib included with the installation in the API folder". How do I do that in Visual Studio? Maybe it's a stupid question but I couldn't really understand how to do that.

 

Thank you for your help,

Doga

3,610 Views
15 Replies
Replies (15)
Message 2 of 16

jeff.pek
Community Manager
Community Manager

Hi Doga -

 

The HSMWorks API is a C++ API, and so would not be supported from VB.NET, except if using P/Invoke facilities.I'm not sure if anyone has successfully tried to connect to the API using P/Invoke. Perhaps others can chime in on that.

 

You could have a managed c++ layer, which could wrap the HSMWorks API, and then call that more directly from VB.NET.

 

Jeff

0 Likes
Message 3 of 16

Anonymous
Not applicable

Are you sure?

 

The API instruction file says: The HSMWorks API allows programmers in Visual Basic .NET, C#, C, and C++ to create add-ins for SolidWorks which also talk/interact with HSMWorks. Note that the SolidWorks macro feature DOES NOT support the HSMWorks API since the macros run in a separate process and hence cannot get access to the HSMWorks data.

 

It'd be very frustrating if the API cannot be accessed with VB.NET. I mean, most of the SW add-ins are written in VB.NET so restricting the HSMWorks API to C++ doesn't make too much sense in my humble opinion.

 

If it is actually compatible with VB.NET, then it is shame there are not enough instructions for VB.NET in the instructions 😞

 

Can you please provide me with more details about this issue? If not do you know who I should contact?

 

 

Thank you in advance,

Doga

0 Likes
Message 4 of 16

jeff.pek
Community Manager
Community Manager

Hi -

 

Yes, I'm quite sure. You *can* use the API from VB.NET, C#, etc., provided that you either use P/Invoke, or have a managed C++ wrapper.

 

Jeff

Message 5 of 16

Anonymous
Not applicable

Great! Can you please explain how to use P/Invoke or a C++ wrapper in a .NET add-in? Or could you at least provide me with a resource/tutorial that I can have a look at? Unfortunately the text file given in the API folder doesn't mention these at all so I'm kinda lost and need your help.

 

Thank you

 

 

0 Likes
Message 6 of 16

jeff.pek
Community Manager
Community Manager

Suire.

 

This is a good general informational site on P/Invoke, with many examples of using native "C-style" APIs from VB.NET and C#.

The HSMWorks API is quite generic in nature, so I think would be relatively straightforward to drive from VB.NET.

 

http://www.pinvoke.net/

 

I'm not aware of any specific examples for this, but if you picked one of the basic APIs, and got that working, then you could build from there to create additional calling interfaces.

 

We are happy to help you make progress here, if you get something set up, and want to share your project with us here, we can help work out any kinks.

 

Jeff

Message 7 of 16

Anonymous
Not applicable

Hello,

 

I was able to call a dll function in my VB.NET code by using the syntax below: 

<DllImport("hsmsw.dll", CallingConvention:=CallingConvention.Cdecl)> _
Public Shared Function HSMWorks_dummy() As Integer
End Function

 

A tutorial on YouTube helped me achieve it. However, HSMWorks_dummy() is only a counter, so each time I call the function, the output value increases by one. I now would like to try something more complex, e.g. the HSMWorks_getVersion function.

 

The text file says: 

/**
Returns the version of HSMWorks running.

@param major The major version number.
@param minor The minor version number.
@param micro The micro version number.
@param build The build number.
*/
HSMWORKS_API unsigned int HSMWorks_getVersion(unsigned int* major, unsigned int* minor, unsigned int* micro, unsigned int* build);

 

As far as I understand, we input the pointers to the unsigned integers in C++. How am I supposed to use this in VB.NET? Here's an idea:

 

<DllImport("hsmsw.dll", CallingConvention:=CallingConvention.Cdecl)>
Public Shared Function HSMWorks_getVersion(ByRef major As Integer, ByRef minor As Integer, ByRef micro As Integer, ByRef build As Integer) As Integer
End Function

 

'To get the values, declare the parameters and call the function

Dim major2 As Int32 = 0

Dim major As UInt32 = CUInt(major2)

Dim minor2 As Int32 = 0

Dim minor As UInt32 = CUInt(minor2)

Dim micro2 As Int32 = 0

Dim micro As UInt32 = CUInt(micro2)

Dim build2 As Int32 = 0

Dim build As UInt32 = CUInt(build2)

HSMWorks_getVersion(major, minor, micro, build)

 

Do you think this makes sense?

 

 

Thank you,

Doga

0 Likes
Message 8 of 16

Anonymous
Not applicable

Yes, but it's probably more complex than is needed.

 

What if you just passed the Int32 items directly as major, minor, micro and build?

 

Jeff

Message 9 of 16

Anonymous
Not applicable

Just tested, it worked either way!

 

Now I would like to create a new job, perform 2D miling based on a sketch and export. The sample code given in the text file looks a bit vague to me.

 

void sampleCode() {
ISldWorksPtr sw; // See SolidWorks documentation for accessing SolidWorks object
IUnknownPtr document = sw->GetActiveDoc();

bool waitForTasks = false;
unsigned int status = HSMWorks_regenerateAll(document, waitForTasks);
if (status != STATUS_OK) {
return;
}
if (!waitForTasks) {
// Update user interface if require
while (true) {
Thread::sleep(1 * 1000000);
status = HSMWorks_updateOperationManager(document);
// if (status == STATUS_OK) { // Ignore error
// break; // error
// }
status = HSMWorks_checkTasks(document); // Do this in a separate thread - only call this every second or so
if (status == STATUS_OK) {
break; // done
}
}
}
status = HSMWorks_abortAllTasks(document); // Nothing to do
if (status != STATUS_OK) {
return;
}
status = HSMWorks_checkAllToolpath(document);
if (status != STATUS_OK) {
return;
}
const wchar_t* path = L"D:\\test.cnc";
status = HSMWorks_exportAll(document, path);
if (status != STATUS_OK) {
return;
}
// Post process - see post manual for help
// Clean up files here
}

 

How am I supposed to create a new job and start 2D miling? Could you please explain that? This is not very clear in the above code.

 

 

Thank you for your help,

Doga

 

0 Likes
Message 10 of 16

jeff.pek
Community Manager
Community Manager

Hi Doga -

 

As far as I can tell, the API does not support creating a new job. So, you'll need to work with a template document that already has one.

 

The most common case is that you would have a base line document, and then you would do some modeling changes (in SOLIDWORKS) and then regenerate the toolpaths.

 

Can you describe your high-level workflow for your addin?

 

Thanks,

  Jeff

0 Likes
Message 11 of 16

Anonymous
Not applicable

What I want the add-in to do is basically creating a G-code for the path of the last created sketch. It is that simple.

 

The manual way to do it is to create a job with respect to a coordinate system, start a Trace (under 2D Miling of HSMWorks), choose any of the flat mills and the 2D sketch/path to be traced, and finally click Post Process to export the G-code.

 

 

Can't I do that using the API? I thought it would be easy 😕

0 Likes
Message 12 of 16

jeff.pek
Community Manager
Community Manager

The best way to do this will be to use a template. If you have a template part, containing the operation you want, then you can open that part, push in the sketch you want to use, then you can use HSMWorks_setObjectGeometry to set the geometry to the sketch. Then you just generate the toolpath and post it.

 

I'm not totally sure that this will work, but I don't think you'll have much success trying to create a new object from scratch.

 

I had hoped you could instantiate an HSMWorks template as an alternative, but it doesn't appear that the API supports that.

 

The engineer who's most familiar with this area is on holiday for another couple of weeks, so I can't get a definitive response. Based on the header, though, I think the above is your best bet.

 

Jeff

0 Likes
Message 13 of 16

Anonymous
Not applicable

I couldn't really understand some terms that you have used in your reply. Why is a template necessary? I've never worked with templates so I'm not really sure what you mean by that. More specifically, how can I do the thing that I've described in my previous answer (e.g. creating a job, starting a Trace/2D Miling, choosing a flat mill) by calling HSMWorks_setObjectGeometry?

 

Can you describe that process in more detail? Also, do you know when exactly I can reach that engineer? I need to get this done soon 😞

 

Thank you

0 Likes
Message 14 of 16

jeff.pek
Community Manager
Community Manager

When I use "template", I'm using it in 2 contexts:

1) A "starter document", already containing relevant job and operation definitions. You'd start with this, making a copy, then add your specific sketch geometry, and then modify the operation to reference that geometry;

2) HSMWorks templates, which are pre-saved operation definitions, which you could add into a new document to accomplish the same thing.

 

It's the former that I'm suggesting.

 

You can't create a job (directly) using the API, and it would be very cumbersome to create a new operation using the API. This is why I'm suggesting use a template-based approach.

 

The engineer I'm talking about will be back around the 24th. I can continue trying to help until then. I don't think he'll give you a different answer, for what it's worth.

 

Jeff

0 Likes
Message 15 of 16

Anonymous
Not applicable

Ok, it is now a bit more clear. But I want to perform this perform on different sets of parts and do not want to be restricted to a template. How can I create a "starter document" that can be applied to any type of part?

 

Also, how am I supposed to do it with HSMWorks_setObjectGeometry? The text file says:

 

/**
Sets the geometry of the specified object. Returns STATUS_OK on success.

@param document The SolidWorks document.
@param id The id of the operation.
@param name identifies the geometry being set and can be any of these:

For jobs:
surfaces

For folders:
None

For operations:
holes
centers
surfaces
check surfaces
entry points
drill positions
contours
machining boundaries
stock boundaries
rest surfaces

IUnknown* ids[16]; // fill with SolidWorks geometry references
if (HSMWorks_setObjectGeometry(document, objectId, "surfaces", sizeof(ids)/sizeof(ids[0])) != STATUS_OK) {
// failed
}

@param ids must be a list of SolidWorks geometry references.
@param size is the size of the ids buffer.
*/
HSMWORKS_API unsigned int HSMWorks_setObjectGeometry(IUnknown* document, unsigned int id, const wchar_t* name, IUnknown** ids, unsigned int size);

 

In my case, what should be name (the geometry being set), and how do I know the id of the operation, as well as the list of SolidWorks geometry references?

 

I'm sorry for asking so many questions but I cannot find any answers online or elsewhere.

 

 

Thank you for your cooperation

0 Likes
Message 16 of 16

jeff.pek
Community Manager
Community Manager

From your description, it sounded like you would have a consistent approach in CAM -- i.e., you said a single trace operation. Is that right? If so, then what you would need to do would be to create -- presumably via the SWX API -- the sketch that you really wanted to use, and then use the setObjectGeometry to tell the operation that that is what you wanted it to work with.

 

So the part itself isn't identical, but the CAM operations would be (with the exception of the geometry).

 

I think the name is just descriptive, so doesn't really matter.

The id is the id of the operation, which you would either just know (since you created the template), or you could look it up via other API methods.

 

I think the list of geometry should probably not be called "Ids" -- this is just an array of objects. So you'd have a way to build an array of objects (one or more) to the sketch geometry, and then feed that to this method as an array.

 

Jeff