Hi,
I attached the file to that post.
But please read the full article first.
- I used Catia v5 R19 and this version comes with a shipped example model “Robot_ABB_S2-Irbl6_2.CATProduct”.I hard link to this in my code. Maybe you have to change this path on your machine.
- I hard linked to the .NET DLL from the MATLAB side. You have to modify this path so it matches your system.
- In the VisualBasic I added the references to INFITF and CATV4IInteropTypeLib. You may have to update this reference so they match you system.
Now let’s start with the actual code.
Please note that this example is extremely trimmed on the shipped example “Robot_ABB_S2-Irbl6_2.CATProduct”.
First of all I like to show you how you can do this in MATLAB without the .NET DLL
catia = actxserver('catia.application');
set(catia,'visible',1);
prj_name = 'C:\Program Files (x86)\Dassault Systemes\B19\intel_a\startup\components\arcWeld\Robot_ABB_S2-Irbl6_2.CATProduct';
invoke(get(catia,'Documents'),'Open',prj_name);
doc = get(catia,'activedocument');
rootproduct = get(doc,'product');
mass = get(get(rootproduct,'Analyze'),'Mass');
area = get(get(rootproduct,'Analyze'),'WetArea');
feature('COM_SafeArraySingleDim', 1)
array = {1;2;3};
invoke(get(rootproduct,'Analyze'),'GetGravityCenter',array);
invoke(catia,'quit');
invoke(catia,'delete');
You see that you don’t get the GravityCenter because the input is passed by reference.
What happens here is:
- MATLAB makes a copy of the variable “array”
- The copy is passed to GetGravityCenter
- The values of the copy are modified
- MATLAB doesn’t read the copy back
MATLAB can’t handle this correctly because MATLAB doesn’t know that the input is passed by reference (the interface is not open).
The only way out here is to move to VB.NET.
You make a Class Library written in VB.NET to communicate with CATIA. The code is more readable as in MATLAB and you can work with the dot notations:
Public Class CatiaLinkLibrary
Dim CATIA As INFITF.Application
Dim rootproduct
Sub StartCatia()
CATIA = CreateObject("CATIA.Application")
End Sub
Sub CloseCatia()
CATIA.Quit()
End Sub
Sub Visible(ByRef mode As Integer)
If mode = 1 Or mode = 0 Then
CATIA.Visible = mode
End If
End Sub
Sub OpenFile(ByRef filename As String)
CATIA.Documents.Open(filename)
rootproduct = CATIA.ActiveDocument.Product()
End Sub
Function GetMass() As Double
Return rootproduct.Analyze.Mass()
End Function
Function GetVolume() As Double
Return rootproduct.Analyze.Volume()
End Function
Function GetArea() As Double
Return rootproduct.Analyze.WetArea()
End Function
Function GetGravityCenter()
Dim gravitycenter(2)
rootproduct.Analyze.GetGravityCenter(gravitycenter)
GetGravityCenter = gravitycenter
End Function
Function GetIntertia()
Dim inertia(8)
rootproduct.Analyze.GetInertia(inertia)
GetIntertia = inertia
End Function
End Class
What on the MATLAB side was a get,set and invoke becomes a nice dot notation. All the command and how they work can be obtained under the link I post earlier. The hardest part for me was to figure out what command to use since the interface CATIA provides is really complex.
You can compile this into a .NET DLL which you call from MATLAB through the NET.addAssembly command. I wrapped a MATLAB class around it to make easier to use on the MATLAB side. The class looks as follows:
classdef CatiaLink < handle
properties
catia;
end
methods
function obj = CatiaLink()
NET.addAssembly('C:\Users\Friedrich\Documents\Visual Studio 2008\Projects\CatiaLinkLibrary\CatiaLinkLibrary\bin\Debug\CatiaLinkLibrary.dll');
obj.catia = CatiaLinkLibrary.CatiaLinkLibrary;
obj.catia.StartCatia;
disp('Catia started')
end
function Visible(obj,mode)
obj.catia.Visible(mode);
end
function Quit(obj)
obj.catia.CloseCatia;
end
function Open(obj,filename)
obj.catia.OpenFile(filename);
end
function mass = GetMass(obj)
mass = obj.catia.GetMass;
end
function vol = GetVolume(obj)
vol = obj.catia.GetVolume;
end
function area = GetArea(obj)
area = obj.catia.GetArea;
end
function cog = GetCenterOfGravity(obj)
tmp = obj.catia.GetGravityCenter;
cog = [tmp(1),tmp(2),tmp(3)];
end
function inertia = GetInertia(obj)
tmp = obj.catia.GetIntertia;
inertia = [tmp(1), tmp(2), tmp(3); ...
tmp(4), tmp(5), tmp(6); ...
tmp(7), tmp(8), tmp(9)];
end
end
end
It’s not a good idea to call NET.addAssembly in a constructor of a class, but I assume for the demo purpose its okay.
Once the DLL is loaded you can access the function of that DLL pretty easily. Most of the functions of the MATLAB class are simply wrapper functions. In the last two functions one has to convert the VB.NET data type into a MATLAB data type so you can work with it.
So the main work is to write a nice working .NET DLL
Once you have the DLL and the MATLAB Class you can call all your functions very nicely:
catia = CatiaLink;
catia.Visible(1)
prj_name = 'C:\Program Files (x86)\Dassault Systemes\B19\intel_a\startup\components\arcWeld\Robot_ABB_S2-Irbl6_2.CATProduct';
catia.Open(prj_name)
area = catia.GetArea
mass = catia.GetMass
volu = catia.GetVolume
cog = catia.GetCenterOfGravity
inertia = catia.GetInertia
catia.Quit
So here a several steps to do but in the end you will have a nice interface on the MATLAB side.
Since the CATIA interface is really complex it’s hard to find a good point to start and the needed functions.
I hope I could clarify the things a bit and I hope this will help you with your project.
Best Answer