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.h"
#include "quadmesh.h"
#include <iostream>

using namespace cm2;


/**
   Very simple C++ program to mesh a square with triangles or quadrangles.
   Uses CM2 TriaMesh and CM2 QuadMesh natively.
   */
int main (int argc, char_t* argv[])
{

   char_t     msg1[256] = "";                    // For error messages.

   try
   {
      DoubleMat            pos;                  // Coordinates of the nodes (2 x nods).
      UIntVec              indices;              // Indices of the boundary nodes (segments).
      UIntMat              connectB;             // Connectivity matrix of the boundary edges.
      UIntMat              connectM;             // Connectivity matrix of the faces (3 x nefs or 4 x nefs).
      
      // Registration of the DLLs.
      triamesh::registration("Licensed to DEMO.", "FC5B65DEDF55");
      quadmesh::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).
      meshtools1d::mesh_straight(pos, 0, 1, 10, indices);  indices.pop_back();
      meshtools1d::mesh_straight(pos, 1, 2, 10, indices);  indices.pop_back();
      meshtools1d::mesh_straigh1(pos, 2, 3, 10, indices);  indices.pop_back();
      meshtools1d::mesh_straight(pos, 3, 0, 10, indices);
      meshtools1d::indices_to_connectE2(indices, connectB);

      // Do the triangle mesh.
      triamesh::mesher     triamesher;           // A triangle mesher.
      triamesh::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.
      meshtools::medit_output("T3.mesh", dataT.pos, dataT.connectM, CM2_FACET3);

      // Do the quadrangle mesh.
      quadmesh::mesher     quadmesher;           // A quadrangle mesher.
      quadmesh::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.
      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.tlb" rename_namespace("triamesh")
#import "ccm2quadmesh.tlb" rename_namespace("quadmesh")
}
#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 and CM2 QuadMesh 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::ImesherPtr                pT3M(__uuidof(triamesh::mesher));   
      quadmesh::ImesherPtr                pQ4M(__uuidof(quadmesh::mesher)); 
      triamesh::Idata_typePtr             pT3D(__uuidof(triamesh::data_type));
      quadmesh::Idata_typePtr             pQ4D(__uuidof(quadmesh::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 = ccm2triameshLib;
using quadmesh = ccm2quadmeshLib;


namespace example_Csharp
{
	/// <summary>
	/// Very simple C# program to mesh a square with triangles or quadrangles.
	/// Uses CM2 TriaMesh and CM2 QuadMesh 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.mesher            mesherT3       = new triamesh.mesher();   
				quadmesh.mesher            mesherQ4       = new quadmesh.mesher(); 

				triamesh.data_type         dataT3         = new triamesh.data_type();
				quadmesh.data_type         dataQ4         = new quadmesh.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 = ccm2triameshLib
Imports cm2quadmesh = ccm2quadmeshLib

'   Very simple VB program to mesh a square with triangles or quadrangles.
'   Uses CM2 TriaMesh and CM2 QuadMesh 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.mesher
         Dim mesherQ4 As New cm2quadmesh.mesher           '
         Dim dataT3 As New cm2triamesh.data_type
         Dim dataQ4 As New cm2quadmesh.data_type

         ' Registration of the DLLs
         mesherT3.registration("Licensed to DEMO.", "FC5B65DEDF55")  ' All cm2triamesh.mesher are now runnable.
         mesherQ4.registration("Licensed to DEMO.", "7FA4A61046AA")  ' All cm2quadmesh.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 and CM2 QuadMesh 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',
  CCM2TRIAMESHLib_TLB    in 'c:\program files\borland\bds\3.0\Imports\CCM2TRIAMESHLib_TLB.pas',
  CCM2QUADMESHLib_TLB    in 'c:\program files\borland\bds\3.0\Imports\CCM2QUADMESHLib_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: CCM2TRIAMESHLib_TLB.mesher;   // Instance of triangle mesher.
  mesherQ4: CCM2QUADMESHLib_TLB.mesher;   // Instance of quadrangle mesher.
  dataT3: CCM2TRIAMESHLib_TLB.data_type;  // Data record for a triangle mesher.
  dataQ4: CCM2QUADMESHLib_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 := CCM2TRIAMESHLib_TLB.Comesher.Create();
     mesherQ4 := CCM2QUADMESHLib_TLB.Comesher.Create();
     dataT3 := CCM2TRIAMESHLib_TLB.Codata_type.Create();
     dataQ4 := CCM2QUADMESHLib_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.

Computing Objects SARL - 25 rue du Maréchal Foch, 78000 Versailles, France.

Limited Liability Company with a capital of 100 000 €.

Registered at Versailles RCS under SIRET number 422 791 038 00033 - EU VAT registration FR59422791038.