COM Interface /code samples
CM2 MeshTools® is written in native C++ but a COM wrapper is also available on Windows to provide an interface for any COM language (C#, Visual Basic, C++ .Net or even Borland Delphi).
C++ (native)
// Native C++ version of the TMSH2D01 test case (mesh of a simple square).
//
#include "meshtools.h"
#include "meshtools1d.h"
#include "triamesh_iso.h"
#include "quadmesh_iso.h"
#include <iostream>
using namespace cm2;
/**
Very simple C++ program to mesh a square with triangles or quadrangles.
Uses CM2 TriaMesh Iso and CM2 QuadMesh Iso natively.
*/
int main (int argc, char_t* argv[])
{
char_t msg1[256] = ""; // For error messages.
try
{
cm2::DoubleMat pos; // Coordinates of the nodes.
cm2::UIntVec indices; // Indices of the boundary nodes.
cm2::UIntMat connectB; // Connectivity matrix of the boundary edges.
cm2::UIntMat connectM; // Connectivity matrix of the elements.
// Registration of the DLLs.
cm2::triamesh_iso::registration("Licensed to DEMO.", "FC5B65DEDF55");
cm2::quadmesh_iso::registration("Licensed to DEMO.", "7FA4A61046AA");
// Construct the four vertices of the square.
pos.push_back( 0.0, 0.0);
pos.push_back(10.0, 0.0);
pos.push_back(10.0, 10.0);
pos.push_back( 0.0, 10.0);
// Mesh the four segments (10 elements on each segment).
cm2::meshtools1d::mesh_straight(pos, 0, 1, 10, indices); indices.pop_back();
cm2::meshtools1d::mesh_straight(pos, 1, 2, 10, indices); indices.pop_back();
cm2::meshtools1d::mesh_straigh1(pos, 2, 3, 10, indices); indices.pop_back();
cm2::meshtools1d::mesh_straight(pos, 3, 0, 10, indices);
cm2::meshtools1d::indices_to_connectE2(indices, connectB);
// Do the triangle mesh.
cm2::triamesh_iso::mesher triamesher; // A triangle mesher.
cm2::triamesh_iso::data_type dataT(pos, connectB); // Input-output data for the mesher.
triamesher.run(dataT);
if (dataT.error_code != 0)
{
::strncpy(msg1, dataT.msg1, 255);
throw "CM2 Exception";
}
// MEDIT output for visualization of the mesh.
cm2::meshtools::medit_output("T3.mesh", dataT.pos, dataT.connectM, CM2_FACET3);
// Do the quadrangle mesh.
cm2::quadmesh_iso::mesher quadmesher; // A quadrangle mesher.
cm2::quadmesh_iso::data_type dataQ(pos, connectB); // Input-output data for the mesher.
quadmesher.run(dataQ);
if (dataQ.error_code != 0)
{
::strncpy(msg1, dataQ.msg1, 255);
throw "CM2 Exception";
}
// MEDIT output for visualization of the mesh.
cm2::meshtools::medit_output("Q4.mesh", dataQ.pos, dataQ.connectM, CM2_FACEQ4);
}
catch (const char* str) // Catch errors.
{
std::cout << str << ": " << msg1 << std::endl;
}
return 0;
}
C++ (through COM)
// COM version of the TMSH2D01 test case (mesh of a simple square).
//
#import "ccm2math1.tlb" rename_namespace("ccm2")
namespace ccm2
{
#import "ccm2misc.tlb" rename_namespace("misc")
#import "ccm2meshtools.tlb" rename_namespace("meshtools")
#import "ccm2meshtools1d.tlb" rename_namespace("meshtools1D")
#import "ccm2triamesh_iso.tlb" rename_namespace("triamesh_iso")
#import "ccm2quadmesh_iso.tlb" rename_namespace("quadmesh_iso")
}
#include "..\common\fe_defs.h"
#include <iostream>
typedef ccm2::meshtools::Celement_type element_type;
using namespace ccm2;
/**
Very simple C++ program to mesh a square with triangles or quadrangles.
Uses CM2 TriaMesh Iso and CM2 QuadMesh Iso through the COM interface.
*/
int main(int argc, char* argv[])
{
wchar_t msg1[256] = L""; // For error messages.
if (FAILED(CoInitialize(NULL)))
{
std::wcout << "Initialization COM failed.\n";
return 0;
}
try
{
IDoubleMatPtr pPos(__uuidof(DoubleMat));
IUIntVecPtr pIndices(__uuidof(UIntVec));
IUIntMatPtr pConnectB(__uuidof(UIntMat));
IUIntMatPtr pConnectM(__uuidof(UIntMat));
meshtools::IMeshToolsPtr pMT(__uuidof(meshtools::MeshTools));
meshtools1D::IMeshTools1DPtr pMT1D(__uuidof(meshtools1D::MeshTools1D));
triamesh_iso::ImesherPtr pT3M(__uuidof(triamesh_iso::mesher));
quadmesh_iso::ImesherPtr pQ4M(__uuidof(quadmesh_iso::mesher));
triamesh_iso::Idata_typePtr pT3D(__uuidof(triamesh_iso::data_type));
quadmesh_iso::Idata_typePtr pQ4D(__uuidof(quadmesh_iso::data_type));
// Registration of the DLLs.
pT3M->registration("Licensed to DEMO.", "FC5B65DEDF55");
pQ4M->registration("Licensed to DEMO.", "7FA4A61046AA");
// Construct the four vertices of the square.
pPos->push_back2( 0.0, 0.0);
pPos->push_back2(10.0, 0.0);
pPos->push_back2(10.0, 10.0);
pPos->push_back2( 0.0, 10.0);
// Mesh the four segments (10 elements on each segment).
pMT1D->mesh_straight1(pPos, 0, 1, 10, pIndices); pIndices->pop_back();
pMT1D->mesh_straight1(pPos, 1, 2, 10, pIndices); pIndices->pop_back();
pMT1D->mesh_straight1(pPos, 2, 3, 10, pIndices); pIndices->pop_back();
pMT1D->mesh_straight1(pPos, 3, 0, 10, pIndices);
pMT1D->indices_to_connectE2(pIndices, pConnectB);
// Do the triangle mesh.
pT3D->put_pos(pPos);
pT3D->put_connectB(pConnectB);
pT3M->run(pT3D);
if (pT3D->error_code != 0) // Catch errors.
{
BSTR bstr1 = 0;
pT3D->get_msg1(&bstr1);
if (bstr1)
::wcsncpy(msg1, bstr1, 255);
::SysFreeString(bstr1);
throw "CM2 Exception";
}
pT3D->get_pos(&pPos);
pT3D->get_connectM(&pConnectM);
pT3D->print_info();
// MEDIT output of the triangle mesh
pMT->medit_output("T3.mesh", pPos, pConnectM, (element_type)CM2_FACET3);
// Do the quadrangle mesh.
pQ4D->put_pos(pPos);
pQ4D->put_connectB(pConnectB);
pQ4M->run(pQ4D);
if (pQ4D->error_code != 0) // Catch errors.
{
BSTR bstr1 = 0;
pQ4D->get_msg1(&bstr1);
if (bstr1)
::wcsncpy(msg1, bstr1, 255);
::SysFreeString(bstr1);
throw "CM2 Exception";
}
pQ4D->get_pos(&pPos);
pQ4D->get_connectM(&pConnectM);
pQ4D->print_info();
// MEDIT output of the quadrangle mesh
pMT->medit_output("Q4.mesh", pPos, pConnectM, (element_type)CM2_FACEQ4);
}
catch (const _com_error& err) // For COM errors.
{
std::wcout << err.ErrorMessage() << std::endl;
}
catch( const char* str ) // For CM2 errors.
{
std::wcout << str << ": " << msg1 << std::endl;
}
CoUninitialize();
return 0;
}
C#
using System;
using ccm2math1Lib;
using meshtools = ccm2meshtoolsLib;
using meshtools1D = ccm2meshtools1dLib;
using triamesh_iso = ccm2triamesh_isoLib;
using quadmesh_iso = ccm2quadmesh_isoLib;
namespace example_Csharp
{
/// <summary>
/// Very simple C# program to mesh a square with triangles or quadrangles.
/// Uses CM2 TriaMesh Iso and CM2 QuadMesh Iso through the COM interface.
/// </summary>
class Class1
{
/// <summary>
/// Main entry.
/// </summary>
[STAThread]
static void Main(string[] args)
{
try
{
DoubleMat pos = new DoubleMat();
UIntVec indices = new UIntVec();
UIntMat connectB = new UIntMat();
UIntMat connectM = new UIntMat();
meshtools.MeshTools MT = new meshtools.MeshTools();
meshtools1D.MeshTools1D MT1D = new meshtools1D.MeshTools1D();
// The mesh generators.
triamesh_iso.mesher mesherT3 = new triamesh_iso.mesher();
quadmesh_iso.mesher mesherQ4 = new quadmesh_iso.mesher();
triamesh_iso.data_type dataT3 = new triamesh_iso.data_type();
quadmesh_iso.data_type dataQ4 = new quadmesh_iso.data_type();
// Registration of the DLLs.
mesherT3.registration("Licensed to DEMO.", "FC5B65DEDF55");
mesherQ4.registration("Licensed to DEMO.", "7FA4A61046AA");
// Construct the four vertices of the square.
pos.push_back2( 0.0, 0.0);
pos.push_back2(10.0, 0.0);
pos.push_back2(10.0, 10.0);
pos.push_back2( 0.0, 10.0);
// Mesh the four segments (10 elements on each segment).
MT1D.mesh_straight1(pos, 0, 1, 10, indices); indices.pop_back();
MT1D.mesh_straight1(pos, 1, 2, 10, indices); indices.pop_back();
MT1D.mesh_straight1(pos, 2, 3, 10, indices); indices.pop_back();
MT1D.mesh_straight1(pos, 3, 0, 10, indices);
MT1D.indices_to_connectE2(indices, connectB);
// Do the triangle mesh.
dataT3.pos = pos;
dataT3.connectB = connectB;
mesherT3.run(dataT3);
if (dataT3.error_code != 0) // Catch errors.
{
string msg1 = dataT3.msg1;
throw new Exception("CM2 Exception: " + msg1);
}
pos = dataT3.pos;
connectM = dataT3.connectM;
dataT3.print_info();
// MEDIT output of the triangle mesh
MT.medit_output("T3.mesh", pos, connectM, meshtools.Celement_type.CM2_FACET3);
// Do the quadrangle mesh.
dataQ4.pos = pos;
dataQ4.connectB = connectB;
mesherQ4.run(dataQ4);
if (dataQ4.error_code != 0) // Catch errors.
{
string msg1 = dataQ4.msg1;
throw new Exception("CM2 Exception: " + msg1);
}
pos = dataQ4.pos;
connectM = dataQ4.connectM;
dataQ4.print_info();
// MEDIT output of the quadrangle mesh
MT.medit_output("Q4.mesh", pos, connectM, meshtools.Celement_type.CM2_FACEQ4);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
}
}
Visual Basic
Imports ccm2math1Lib
Imports cm2meshtools = ccm2meshtoolsLib
Imports cm2meshtools1d = ccm2meshtools1dLib
Imports cm2triamesh_iso = ccm2triamesh_isoLib
Imports cm2quadmesh_iso = ccm2quadmesh_isoLib
' Very simple VB program to mesh a square with triangles or quadrangles.
' Uses CM2 TriaMesh Iso and CM2 QuadMesh Iso through the COM interface.
Module Module1
Sub Main()
Dim msg1 As String ' For error messages.
Try
Dim pos As New DoubleMat
Dim indices As New UIntVec
Dim connectB As New UIntMat
Dim connectM As New UIntMat
Dim MT As New cm2meshtools.MeshTools
Dim MT1D As New cm2meshtools1d.MeshTools1D
Dim mesherT3 As New cm2triamesh_iso.mesher
Dim mesherQ4 As New cm2quadmesh_iso.mesher '
Dim dataT3 As New cm2triamesh_iso.data_type
Dim dataQ4 As New cm2quadmesh_iso.data_type
' Registration of the DLLs
mesherT3.registration("Licensed to DEMO.", "FC5B65DEDF55") ' All cm2triamesh_iso.mesher are now runnable.
mesherQ4.registration("Licensed to DEMO.", "7FA4A61046AA") ' All cm2quadmesh_iso.mesher are now runnable.
' Construct the four vertices of the square.
pos.push_back2(0.0, 0.0)
pos.push_back2(10.0, 0.0)
pos.push_back2(10.0, 10.0)
pos.push_back2(0.0, 10.0)
' Mesh the four segments (10 elements on each segment).
MT1D.mesh_straight1(pos, 0, 1, 10, indices)
indices.pop_back()
MT1D.mesh_straight1(pos, 1, 2, 10, indices)
indices.pop_back()
MT1D.mesh_straight1(pos, 2, 3, 10, indices)
indices.pop_back()
MT1D.mesh_straight1(pos, 3, 0, 10, indices)
MT1D.indices_to_connectE2(indices, connectB)
' Do the triangle mesh.
dataT3.pos = pos
dataT3.connectB = connectB
mesherT3.run(dataT3)
If dataT3.error_code <> 0 Then
msg1 = dataT3.msg1
Throw New Exception("CM2 Exception: " + msg1)
End If
pos = dataT3.pos
connectM = dataT3.connectM
dataT3.print_info()
' MEDIT output of the triangle mesh
MT.medit_output("T3.mesh", pos, connectM, cm2meshtools.Celement_type.CM2_FACET3)
' Do the quadrangle mesh
dataQ4.pos = pos
dataQ4.connectB = connectB
mesherQ4.run(dataQ4)
If dataQ4.error_code <> 0 Then
msg1 = dataQ4.msg1
Throw New Exception("CM2 Exception: " + msg1)
End If
pos = dataQ4.pos
connectM = dataQ4.connectM
dataQ4.print_info()
' MEDIT output of the quadrangle mesh
MT.medit_output("Q4.mesh", pos, connectM, cm2meshtools.Celement_type.CM2_FACEQ4)
Catch ex As Exception
Console.WriteLine(ex.Message())
End Try
End Sub
End Module
Borland Delphi
// Very simple Delphi program to mesh a square with triangles or quadrangles.
// Uses CM2 TriaMesh Iso and CM2 QuadMesh Iso through the COM interface.
program Example;
{$APPTYPE CONSOLE}
// Import the MeshTools TLB components.
uses
SysUtils,
ActiveX,
ComObj,
CCM2MATH1Lib_TLB in 'c:\program files\borland\bds\3.0\Imports\CCM2MATH1Lib_TLB.pas',
CCM2MESHTOOLSLib_TLB in 'c:\program files\borland\bds\3.0\Imports\CCM2MESHTOOLSLib_TLB.pas',
CCM2MESHTOOLS1DLib_TLB in 'c:\program files\borland\bds\3.0\Imports\CCM2MESHTOOLS1DLib_TLB.pas',
CCM2TRIAMESH_ISOLib_TLB in 'c:\program files\borland\bds\3.0\Imports\CCM2TRIAMESH_ISOLib_TLB.pas',
CCM2QUADMESH_ISOLib_TLB in 'c:\program files\borland\bds\3.0\Imports\CCM2QUADMESH_ISOLib_TLB.pas';
var
pos: DoubleMat; // To store the coordinates matrix.
indices: UIntVec; // To store the indices of the boundary nodes.
connectB: UIntMat; // To store the connectivity matrix of the boundary edges.
connectM: UIntMat; // To store the connectivity of the 2-D mesh.
MT: MeshTools; // To use the procedures in the meshtools lib.
MT1D: MeshTools1D; // To use the procedures in the meshtools1D lib.
mesherT3: CCM2TRIAMESH_ISOLib_TLB.mesher; // Instance of triangle mesher.
mesherQ4: CCM2QUADMESH_ISOLib_TLB.mesher; // Instance of quadrangle mesher.
dataT3: CCM2TRIAMESH_ISOLib_TLB.data_type; // Data record for a triangle mesher.
dataQ4: CCM2QUADMESH_ISOLib_TLB.data_type; // Data record for a quadrangle mesher.
begin
// Initialize COM.
ActiveX.CoInitialize (nil);
try
// Creation of the interfaces.
pos := CoCDoubleMat.Create();
indices := CoCUIntVec.Create();
connectB := CoCUIntMat.Create();
connectM := CoCUIntMat.Create();
MT := CoMeshTools.Create();
MT1D := CoMeshTools1D.Create();
mesherT3 := CCM2TRIAMESH_ISOLib_TLB.Comesher.Create();
mesherQ4 := CCM2QUADMESH_ISOLib_TLB.Comesher.Create();
dataT3 := CCM2TRIAMESH_ISOLib_TLB.Codata_type.Create();
dataQ4 := CCM2QUADMESH_ISOLib_TLB.Codata_type.Create();
// REGISTRATION OF THE DLLS.
mesherT3.registration('Licensed to DEMO.', 'B52D9111BD0C');
mesherQ4.registration('Licensed to DEMO.', 'F4765058FC55');
// THE FOUR VERTICES OF THE SQUARE.
pos.push_back2(0.0, 0.0);
pos.push_back2(10.0, 0.0);
pos.push_back2(10.0, 10.0);
pos.push_back2(0.0, 10.0);
// MESH THE FOUR SEGMENTS (10 ELEMENTS ON EACH SEGMENT).
MT1D.mesh_straight1(pos, 0, 1, 10, indices); // 10 nodes between node #0 and node #1.
indices.pop_back();
MT1D.mesh_straight1(pos, 1, 2, 10, indices); // 10 nodes between node #1 and node #2.
indices.pop_back();
MT1D.mesh_straight1(pos, 2, 3, 10, indices); // 10 nodes between node #2 and node #3.
indices.pop_back();
MT1D.mesh_straight1(pos, 3, 0, 10, indices); // 10 nodes between node #3 and node #0.
MT1D.indices_to_connectE2(indices, connectB); // Create edges from the set of consecutive nodes in 'indices'
// DO THE TRIANGLE MESH.
dataT3.pos := pos; // The coordinates.
dataT3.connectB := connectB; // The boundary.
mesherT3.run(dataT3); // Run the mesher.
if dataT3.Get_error_code() <> 0 then
raise Exception.Create('CM2 Exception: ' + dataT3.msg1); // Error reporting (license error, boundary error...)
pos := dataT3.pos; // The coordinate matrix has been extended with new nodes.
connectM := dataT3.connectM; // The triangle connectivity matrix.
dataT3.print_info(); // Print some info on console about the generated mesh.
// MEDIT OUTPUT OF THE TRIANGLE MESH.
MT.medit_output('T3.mesh', pos, connectM, CM2_FACET3);
// DO THE SAME WITH THE QUAD MESHER.
dataQ4.pos := pos;
dataQ4.connectB := connectB;
mesherQ4.run(dataQ4);
if dataQ4.error_code <> 0 then
raise Exception.Create('CM2 Exception: ' + dataQ4.msg1);
pos := dataQ4.pos;
connectM := dataQ4.connectM;
dataQ4.print_info();
MT.medit_output('Q4.mesh', pos, connectM, CM2_FACEQ4);
except
on E: Exception do WriteLn(E.Message);
end;
// ActiveX.CoUninitialize;
end.