{************************************************************}
{                 Delphi VCL Extensions                      }
{                                                            }
{             Wrapper for MeshBuilder.dll project            }
{                                                            }
{      Copyright (c) 2012-2013 SoftGold software company     }
{                                                            }
{************************************************************}

unit sgMeshBuilderWrapper;
{$INCLUDE SGDXF.INC}

interface

uses
  Windows, SysUtils, Classes, sgConsts, sgFunction;

const
  RESULT_SUCCESS = 0;
  RESULT_ERROR = -1;
  RESULT_ERROR_IN_PARAMS = -2;

type
//  PsgVertex = ^TsgVertex;
//  TsgVertex = packed record
//    X: Double;
//    Y: Double;
//    Z: Double;
//  end;
  PsgVertex = PFPoint;
  TsgVertex = TFPoint;

  PsgTriangle = ^TsgTriangle;
  TsgTriangle = packed record
    Corner1: TsgVertex;
    Corner2: TsgVertex;
    Corner3: TsgVertex;
    Normal:  TsgVertex;
  end;

  PsgDimTriangle = ^TsgDimTriangle;
  TsgDimTriangle = packed record
    CountTriangle: Integer;
    Triangle: array [0..0] of TsgTriangle;
  end;

  PsgBeginData = ^TsgBeginData;
  TsgBeginData = packed record
    PointX: TsgVertex;
    PointY: TsgVertex;
    PointZ: TsgVertex;
    Point0: TsgVertex;
    MatrixPlus: Double;
    PerformOffAllFlags: Integer;
  end;

  PsgMatrixData = ^TsgMatrixData;
  TsgMatrixData = packed record
    PointX: TsgVertex;
    PointY: TsgVertex;
    PointZ: TsgVertex;
    Point0: TsgVertex;
  end;

  PsgDLLParam = ^TsgDLLParam;
  TsgDLLParam = packed record
    GetTriangleFuncParam: Pointer;
  end;

  PsgTestLine = ^TsgTestLine;
  TsgTestLine = packed record
    Color: Integer;
    Point1: TsgVertex;
    Point2: TsgVertex;
    Creator: Pointer;
  end;


  PsgIntervalData = ^TsgIntervalData;
  TsgIntervalData = packed record
    RangeaA: Double;
    RangeaB: Double;
    PointA: TsgVertex;
    PointB: TsgVertex;
    OrientationEdge: Integer;
    OrientationCoEdge: Integer;
  end;

  PsgPositionData = ^TsgPositionData;
  TsgPositionData = packed record
    Center: TsgVertex;
    Normal: TsgVertex;
  end;

  PsgEllipseData = ^TsgEllipseData;
  TsgEllipseData = packed record
    Positon: TsgPositionData;
    MajorAxis: TsgVertex;
    RadiusRatio: Double;
    IntervalFlag: Integer;
    Interval: TsgIntervalData;
  end;

  PsgStraightData = ^TsgStraightData;
  TsgStraightData = packed record
    Direction: TsgVertex;
    ParamScale: Double;
    Root: TsgVertex;
    IntervalFlag: Integer;
    Interval: TsgIntervalData;
  end;

  PsgConeData = ^TsgConeData;
  TsgConeData = packed record
    BaseEllipse: TsgEllipseData;
    SinAngle: Double;
    CosinAngle: Double;
    ReverseU: Integer;
    UParamScaling: Double;
    ReverseFace: Integer;
  end;

  PsgPlaneData = ^TsgPlaneData;
  TsgPlaneData = packed record
    Positon: TsgPositionData;
    UDeriv: TsgVertex;
    ReverseV: Integer;
    ReverseFace: Integer;
  end;

  PsgTorusData = ^TsgTorusData;
  TsgTorusData = packed record
    Positon: TsgPositionData;
    MajorRadius: Double;
    MinorRadius: Double;
    UVOridir: TsgVertex;
    ReverseV: Integer;
    ReverseFace: Integer;
  end;

  PsgSphereData = ^TsgSphereData;
  TsgSphereData = packed record
    Positon: TsgPositionData;
    Radius: Double;
    UVOridir: TsgVertex;
    PoleDir: TsgVertex;
    ReverseV: Integer;
    ReverseFace: Integer;
  end;

  PsgArcData = ^TsgArcData;
  TsgArcData = packed record
    BaseEllipse: TsgEllipseData;
    Point1: TsgVertex;
    Point2: TsgVertex;
  end;

  PsgLineData = ^TsgLineData;
  TsgLineData = packed record
    Point1: TsgVertex;
    Point2: TsgVertex;
  end;

  PsgListData = ^TsgListData;
  TsgListData = packed record
    Count: Integer;
    SizeElement: Integer;
    ListData: Pointer;
  end;

  PsgBSplineData = ^TsgBSplineData;
  TsgBSplineData = packed record
    Degree: Integer;
    Periodic: Integer;
    CheckRaional: Integer;
    ControlPoints: TsgListData; //TFPointList
    Weights: TsgListData; //TsgDoubleList
    Knots: TsgListData; //TsgDoubleList
    Multiplicities: TsgListData; //TsgIntegerList
    IntervalFlag: Integer;
    Interval: TsgIntervalData;
  end;

  PsgSplineSurfaceData = ^TsgSplineSurfaceData;
  TsgSplineSurfaceData = packed record
    SplineU: TsgBSplineData;
    SplineV: TsgBSplineData;
    //sum(v-Knotmultiplicity)+1–v degree)*(sum(u-Knotmultiplicity)+ 1–u degree)
    ControlPointsUV: TsgListData;
    WeightsUV: TsgListData;
    ReverseFace: Integer;
  end;

  PsgInitParam = ^TsgInitParam;
  TsgInitParam = packed record
    Parser: Pointer;
    Creator: Pointer;
    GetWire: Pointer;
    GetIso: Pointer;
    GetLine: Pointer;
    StopFunc: Pointer;
    DeviationCoefficien: Double;
    CalcTopogy: Integer;
    Multithreading: Integer;
  end;

  PsgWireData = ^ TsgWireData;
  TsgWireData = packed record
    CoEdgeReverse: Integer;
    EdgeReverse: Integer;
  end;

  PsgConvertData = ^TsgConvertData;
  TsgConvertData = packed record
    File3DType: Integer;
    File3DName: PAnsiChar;
    IndexFaceMap: Integer;
    Parser: Pointer;
  end;

  PsgParamTriangle = ^TsgParamTriangle;
  TsgParamTriangle = packed record
    ASelf: Pointer;
    MeshPointer: Pointer;
    VertexPointer: Pointer;
  end;

  PsgContext = ^TsgContext;
  TsgContext = packed record
    MagicBegin: Integer;
    Context: Pointer;
    MagicEnd: Integer;
  end;

  PsgSegmentData = ^TsgSegmentData;
  TsgSegmentData = packed record
    FoundColor: Integer;
    Red: Double;
    Green: Double;
    Blue: Double;
    NameDataBoundedByZero: Pointer;
{$IFDEF SG_BREP_TOPOLOGY}
    ExtData: Integer;
    Volume: Double;
    Area: Double;
    CenterMass: TsgVertex;
{$ENDIF}
  end;

  TsgGetTriangleFunc = procedure(DimTriangle: PsgDimTriangle;
    Params: Pointer); cdecl;
  TsgNewFaceGroupFunc = procedure(Params: Pointer); cdecl;
  TsgBeginSegment = procedure(Params: Pointer; IndexFaceMap: Integer; SegmentData: PsgSegmentData); cdecl;
  TsgEndSegment = procedure(Params: Pointer); cdecl;
  TsgCallBackLine = procedure(Line: PsgTestLine); cdecl;
  TsgCallBackStop = function(Params: Pointer; ACurrent, AMaxCount: Integer): Integer; cdecl;

  PsgInitMeshBuilderData = ^TsgInitMeshBuilderData;
  TsgInitMeshBuilderData = record
     File3DType: Integer;
     File3DName: PAnsiChar;
     IndexFaceMap: Integer;
     DrawWireFunc: Pointer;
     DrawISOFunc: Pointer;
     DrawTestFunc: Pointer;
     TriangleFunc: Pointer;
     Self: Pointer;
     Creator: Pointer;
     MeshParam: Pointer;
     NewFaceGroupFunc: Pointer;
     StopFunc: Pointer;
     BeginSegment: Pointer;
     EndSegment: Pointer;
  end;

  PsgEndMakeShapeData = ^TsgEndMakeShapeData;
  TsgEndMakeShapeData = packed record
    GetTriangleFunc: TsgGetTriangleFunc;
    Params: PsgDLLParam;
    NewFaceGroupFunc: TsgNewFaceGroupFunc;
    BeginSegment: TsgBeginSegment;
    EndSegment: TsgEndSegment;
  end;

  PsgFile3DVectFileData = ^TsgFile3DVectFileData;
  TsgFile3DVectFileData = TsgEndMakeShapeData;


function sgInitContext(AContext: PsgContext): Integer;
function sgFreeContext(AContext: PsgContext): Integer;

//Shape
function sgBeginMakeShape(AContext: PsgContext; const AData: TsgBeginData): Integer;
//function sgEndMakeShape(const AContext: TsgContext; GetTriangleFunc: TsgGetTriangleFunc;
//  const Params: TsgDLLParam; NewFaceGroupFunc: TsgNewFaceGroupFunc): Integer;
function sgEndMakeShape(AContext: PsgContext; const AData: TsgEndMakeShapeData): Integer;
function sgOuterShape(AContext: PsgContext; const AData: TsgEndMakeShapeData): Integer;
function sgFailureMakeShape(AContext: PsgContext): Integer;
// Curve
function sgAddEllipse(AContext: PsgContext; const AData: TsgEllipseData): Integer;
function sgAddArc(AContext: PsgContext; const AData: TsgArcData): Integer;
function sgAddLine(AContext: PsgContext; const AData: TsgLineData): Integer;
function sgAddStraight(AContext: PsgContext; const AData: TsgStraightData): Integer;
function sgAddBSpline(AContext: PsgContext; const AData: TsgBSplineData): Integer;

// Surface
function sgAddConeSurface(AContext: PsgContext; const AData: TsgConeData): Integer;
function sgAddPlaneSurface(AContext: PsgContext; const AData: TsgPlaneData): Integer;
function sgAddTorusSurface(AContext: PsgContext; const AData: TsgTorusData): Integer;
function sgAddSplineSurface(AContext: PsgContext; const AData: TsgSplineSurfaceData): Integer;
function sgAddSphereSurface(AContext: PsgContext; const AData: TsgSphereData): Integer;

//Wire
function sgEndWire(AContext: PsgContext; const AData: TsgWireData): Integer;
function sgBeginWire(AContext: PsgContext): Integer;
//Support
function sgInitParser(AContext: PsgContext; const AData: TsgInitParam): Integer;
function sgInvertMatrix(const AData: TsgMatrixData;
  const InvertMatrix: TsgMatrixData): Integer;

// Test load dll
function IsLoadMeshBuilderDll: Boolean;

// Iges Step
function sgFile3DVectFile(AContext: PsgContext; const AData: TsgConvertData;
  const AData2: TsgFile3DVectFileData): Integer;

function MakeVertex(const APoint: TFPoint): TsgVertex;

procedure sgLockCallMeshBuilder;
procedure sgUnLockCallMeshBuilder;


implementation

{$IFNDEF BCB}
threadvar
{$ELSE}
var
{$ENDIF}
  LockCallMeshBuilder: Boolean;

procedure sgLockCallMeshBuilder;
begin
  LockCallMeshBuilder := True;
end;

procedure sgUnLockCallMeshBuilder;
begin
  LockCallMeshBuilder := False;
end;

function sgMeshBuilderNotUsing: Boolean;
begin
  Result := LockCallMeshBuilder or cnstMeshBuilderNotUsing;
end;

function MakeVertex(const APoint: TFPoint): TsgVertex;
begin
  Result.X := APoint.X;
  Result.Y := APoint.Y;
  Result.Z := APoint.Z;
end;

{$IFNDEF CS_STATIC_MESHBUILDER_DLL}
type
  TsgInitContextFunc = function(AContext: PsgContext): Integer; cdecl;
  TsgFreeContextFunc = function(AContext: PsgContext): Integer; cdecl;
//  TsgEndMakeShapeFunc = function(AContext: PsgContext; GetTriangleFunc: TsgGetTriangleFunc;
//    Params: PsgDLLParam; NewFaceGroupFunc: TsgNewFaceGroupFunc): Integer; cdecl;
  TsgEndMakeShapeFunc = function(AContext: PsgContext; AData: PsgEndMakeShapeData): Integer; cdecl;
  TsgOuterShapeFunc = function(AContext: PsgContext; AData: PsgEndMakeShapeData): Integer; cdecl;
  TsgFailureMakeShapeFunc = function(AContext: PsgContext): Integer; cdecl;
  TsgFile3DVectFileFunc = function(AContext: PsgContext; AData: PsgConvertData;
    AData2: PsgFile3DVectFileData): Integer; cdecl;
  TsgBeginMakeShapeFunc = function(AContext: PsgContext; AData: PsgBeginData): Integer; cdecl;
  TsgInvertMatrixFunc =function(AData: PsgMatrixData;
    InvertMatrix: PsgMatrixData): Integer; cdecl;
  TsgEndWireFunc = function(AContext: PsgContext; const AData: PsgWireData): Integer; cdecl;
  TsgBeginWireFunc = function(AContext: PsgContext): Integer; cdecl;
  TsgAddConeSurfaceFunc = function(AContext: PsgContext; AData: PsgConeData): Integer; cdecl;
  TsgAddPlaneSurfaceFunc = function(AContext: PsgContext; AData: PsgPlaneData): Integer; cdecl;
  TsgAddTorusSurfaceFunc = function(AContext: PsgContext; AData: PsgTorusData): Integer; cdecl;
  TsgAddSphereSurfaceFunc = function(AContext: PsgContext; AData: PsgSphereData): Integer; cdecl;
  TsgAddSplineSurfaceFunc = function(AContext: PsgContext; AData: PsgSplineSurfaceData): Integer; cdecl;
  TsgAddEllipseFunc = function(AContext: PsgContext; AData: PsgEllipseData): Integer; cdecl;
  TsgAddArcFunc = function(AContext: PsgContext; AData: PsgArcData): Integer; cdecl;
  TsgAddLineFunc = function(AContext: PsgContext; AData: PsgLineData): Integer; cdecl;
  TsgAddStraightFunc = function(AContext: PsgContext; AData: PsgStraightData): Integer; cdecl;
  TsgAddBSplineFunc = function(AContext: PsgContext; AData: PsgBSplineData): Integer; cdecl;
  TsgInitParserFunc = function(AContext: PsgContext; AData: PsgInitParam): Integer; cdecl;

var
  MeshBuilderDllInst: HMODULE = 0;
  sgInitContextFunc: TsgInitContextFunc = nil;
  sgFreeContextFunc: TsgFreeContextFunc = nil;
  sgEndMakeShapeFunc: TsgEndMakeShapeFunc = nil;
  sgOuterShapeFunc: TsgOuterShapeFunc = nil;
  sgFailureMakeShapeFunc: TsgFailureMakeShapeFunc = nil;
  sgFile3DVectFileFunc: TsgFile3DVectFileFunc = nil;
  sgBeginMakeShapeFunc: TsgBeginMakeShapeFunc = nil;
  sgInvertMatrixFunc: TsgInvertMatrixFunc = nil;
  sgEndWireFunc: TsgEndWireFunc = nil;
  sgBeginWireFunc: TsgBeginWireFunc = nil;
  sgAddConeSurfaceFunc: TsgAddConeSurfaceFunc = nil;
  sgAddPlaneSurfaceFunc: TsgAddPlaneSurfaceFunc = nil;
  sgAddTorusSurfaceFunc: TsgAddTorusSurfaceFunc = nil;
  sgAddSphereSurfaceFunc: TsgAddSphereSurfaceFunc = nil;
  sgAddSplineSurfaceFunc: TsgAddSplineSurfaceFunc = nil;
  sgAddEllipseFunc: TsgAddEllipseFunc = nil;
  sgAddArcFunc: TsgAddArcFunc = nil;
  sgAddLineFunc: TsgAddLineFunc = nil;
  sgAddStraightFunc: TsgAddStraightFunc = nil;
  sgAddBSplineFunc: TsgAddBSplineFunc = nil;
  sgInitParserFunc: TsgInitParserFunc = nil;

procedure InitMeshBuilderDll(const ADLLPath: string);
var
  vPath, vDllPath: string;
begin
  if cnstMeshBuilderDllExistsTestWas or cnstMeshBuilderNotUsing then Exit;
  vPath := GetCurrentDir;
  try
    vDllPath := AddLastSlash(ADLLPath);
    if vDllPath <> '' then
      SetCurrentDir(vDllPath);
    MeshBuilderDllInst := LoadLibrary(PChar(vDllPath + MeshBuilderDll));
    cnstMeshBuilderDllExistsTestWas := True;
    if MeshBuilderDllInst <> 0 then
    begin
      sgInitContextFunc := GetProcAddress(MeshBuilderDllInst, 'sgInitContext');
      sgFreeContextFunc := GetProcAddress(MeshBuilderDllInst, 'sgFreeContext');
      sgEndMakeShapeFunc := GetProcAddress(MeshBuilderDllInst, 'sgEndMakeShape');
      sgOuterShapeFunc := GetProcAddress(MeshBuilderDllInst, 'sgOuterShape');
      sgFailureMakeShapeFunc := GetProcAddress(MeshBuilderDllInst, 'sgFailureMakeShape');
      sgFile3DVectFileFunc := GetProcAddress(MeshBuilderDllInst, 'sgFile3DVectFile');
      sgBeginMakeShapeFunc := GetProcAddress(MeshBuilderDllInst, 'sgBeginMakeShape');
      sgInvertMatrixFunc := GetProcAddress(MeshBuilderDllInst, 'sgInvertMatrix');
      sgEndWireFunc := GetProcAddress(MeshBuilderDllInst, 'sgEndWire');
      sgBeginWireFunc := GetProcAddress(MeshBuilderDllInst, 'sgBeginWire');
      sgAddConeSurfaceFunc := GetProcAddress(MeshBuilderDllInst, 'sgAddConeSurface');
      sgAddPlaneSurfaceFunc := GetProcAddress(MeshBuilderDllInst, 'sgAddPlaneSurface');
      sgAddTorusSurfaceFunc := GetProcAddress(MeshBuilderDllInst, 'sgAddTorusSurface');
      sgAddSphereSurfaceFunc := GetProcAddress(MeshBuilderDllInst, 'sgAddSphereSurface');
      sgAddSplineSurfaceFunc := GetProcAddress(MeshBuilderDllInst, 'sgAddSplineSurface');
      sgAddEllipseFunc := GetProcAddress(MeshBuilderDllInst, 'sgAddEllipse');
      sgAddArcFunc := GetProcAddress(MeshBuilderDllInst, 'sgAddArc');
      sgAddLineFunc := GetProcAddress(MeshBuilderDllInst, 'sgAddLine');
      sgAddStraightFunc := GetProcAddress(MeshBuilderDllInst, 'sgAddStraight');
      sgAddBSplineFunc := GetProcAddress(MeshBuilderDllInst, 'sgAddBSpline');
      sgInitParserFunc := GetProcAddress(MeshBuilderDllInst, 'sgInitParser');
    end;
  finally
    SetCurrentDir(vPath);
  end;
end;

procedure FreeMeshBuilderDll;
begin
  if MeshBuilderDllInst <> 0 then
    FreeLibrary(MeshBuilderDllInst);
end;
{$ELSE}
  function sgInitContextFunc(AContext: PsgContext): Integer; cdecl;
    external MeshBuilderDll name 'sgInitContext';
  function sgFreeContextFunc(AContext: PsgContext): Integer; cdecl;
    external MeshBuilderDll name 'sgFreeContext';
//  function sgEndMakeShapeFunc(AContext: PsgContext; GetTriangleFunc: TsgGetTriangleFunc;
//    Params: PsgDLLParam; NewFaceGroupFunc: TsgNewFaceGroupFunc): Integer; cdecl;
//    external MeshBuilderDll name 'sgEndMakeShape';
  function sgEndMakeShapeFunc(AContext: PsgContext; AData: PsgEndMakeShapeData): Integer; cdecl;
    external MeshBuilderDll name 'sgEndMakeShape';
  function sgOuterShapeFunc(AContext: PsgContext; AData: PsgEndMakeShapeData): Integer; cdecl;
    external MeshBuilderDll name 'sgOuterShape';
  function sgFailureMakeShapeFunc(AContext: PsgContext): Integer; cdecl;
    external MeshBuilderDll name 'sgFailureMakeShape';
  function sgFile3DVectFileFunc(AContext: PsgContext; AData: PsgConvertData;
    AData2: PsgFile3DVectFileData): Integer; cdecl;
    external MeshBuilderDll name 'sgFile3DVectFile';
  function sgBeginMakeShapeFunc(AContext: PsgContext; AData: PsgBeginData): Integer; cdecl;
    external MeshBuilderDll name 'sgBeginMakeShape';
  function sgInvertMatrixFunc(AData: PsgMatrixData;
    InvertMatrix: PsgMatrixData): Integer; cdecl;
    external MeshBuilderDll name 'sgInvertMatrix';
  function sgEndWireFunc(AContext: PsgContext; const AData: PsgWireData): Integer; cdecl;
    external MeshBuilderDll name 'sgEndWire';
  function sgBeginWireFunc(AContext: PsgContext): Integer; cdecl;
    external MeshBuilderDll name 'sgBeginWire';
  function sgAddConeSurfaceFunc(AContext: PsgContext; AData: PsgConeData): Integer; cdecl;
    external MeshBuilderDll name 'sgAddConeSurface';
  function sgAddPlaneSurfaceFunc(AContext: PsgContext; AData: PsgPlaneData): Integer; cdecl;
    external MeshBuilderDll name 'sgAddPlaneSurface';
  function sgAddTorusSurfaceFunc(AContext: PsgContext; AData: PsgTorusData): Integer; cdecl;
    external MeshBuilderDll name 'sgAddTorusSurface';
  function sgAddSphereSurfaceFunc(AContext: PsgContext; AData: PsgSphereData): Integer; cdecl;
    external MeshBuilderDll name 'sgAddSphereSurface';
  function sgAddSplineSurfaceFunc(AContext: PsgContext; AData: PsgSplineSurfaceData): Integer; cdecl;
    external MeshBuilderDll name 'sgAddSplineSurface';
  function sgAddEllipseFunc(AContext: PsgContext; AData: PsgEllipseData): Integer; cdecl;
    external MeshBuilderDll name 'sgAddEllipse';
  function sgAddArcFunc(AContext: PsgContext; AData: PsgArcData): Integer; cdecl;
    external MeshBuilderDll name 'sgAddArc';
  function sgAddLineFunc(AContext: PsgContext; AData: PsgLineData): Integer; cdecl;
    external MeshBuilderDll name 'sgAddLine';
  function sgAddStraightFunc(AContext: PsgContext; AData: PsgStraightData): Integer; cdecl;
    external MeshBuilderDll name 'sgAddStraight';
  function sgAddBSplineFunc(AContext: PsgContext; AData: PsgBSplineData): Integer; cdecl;
    external MeshBuilderDll name 'sgAddBSpline';
  function sgInitParserFunc(AContext: PsgContext; AData: PsgInitParam): Integer; cdecl;
    external MeshBuilderDll name 'sgInitParser';
{$ENDIF}

function sgInitContext(AContext: PsgContext): Integer;
begin
  try
    if @sgInitContextFunc <> nil then
      Result := sgInitContextFunc(AContext)
    else
      Result := RESULT_ERROR;
  except
    Result := RESULT_ERROR;
  end;
end;

function sgFreeContext(AContext: PsgContext): Integer;
begin
  try
    if @sgFreeContextFunc <> nil then
      Result := sgFreeContextFunc(AContext)
    else
      Result := RESULT_ERROR;
  except
    Result := RESULT_ERROR;
  end;
end;

//function sgEndMakeShape(const AContext: TsgContext; GetTriangleFunc: TsgGetTriangleFunc;
//  const Params: TsgDLLParam; NewFaceGroupFunc: TsgNewFaceGroupFunc): Integer;
//begin
//  if @sgEndMakeShapeFunc <> nil then
//    Result := sgEndMakeShapeFunc(@AContext, GetTriangleFunc, @Params, NewFaceGroupFunc)
//  else
//    Result := RESULT_ERROR;
//end;

function sgEndMakeShape(AContext: PsgContext; const AData: TsgEndMakeShapeData): Integer;
begin
  try
    if @sgEndMakeShapeFunc <> nil then
      Result := sgEndMakeShapeFunc(AContext, @AData)
    else
      Result := RESULT_ERROR;
  except
    Result := RESULT_ERROR;
  end;
end;

function sgOuterShape(AContext: PsgContext; const AData: TsgEndMakeShapeData): Integer;
begin
  try
    if @sgOuterShapeFunc <> nil then
      Result := sgOuterShapeFunc(AContext, @AData)
    else
      Result := RESULT_ERROR;
  except
    Result := RESULT_ERROR;
  end;
end;

function sgFailureMakeShape(AContext: PsgContext): Integer;
begin
  try
    if @sgFailureMakeShapeFunc <> nil then
      Result := sgFailureMakeShapeFunc(AContext)
    else
      Result := RESULT_ERROR;
  except
    Result := RESULT_ERROR;
  end;
end;

function sgFile3DVectFile(AContext: PsgContext; const AData: TsgConvertData;
  const AData2: TsgFile3DVectFileData): Integer;
begin
  try
    if @sgFile3DVectFileFunc <> nil then
      Result := sgFile3DVectFileFunc(AContext, @AData, @AData2)
    else
      Result := RESULT_ERROR;
  except
    Result := RESULT_ERROR;
  end;
end;

function sgBeginMakeShape(AContext: PsgContext; const AData: TsgBeginData): Integer;
begin
  try
    if @sgBeginMakeShapeFunc <> nil then
      Result := sgBeginMakeShapeFunc(AContext, @AData)
    else
      Result := RESULT_ERROR;
  except
    Result := RESULT_ERROR;
  end;
end;

function sgInvertMatrix(const AData: TsgMatrixData;
  const InvertMatrix: TsgMatrixData): Integer;
begin
  try
    if @sgInvertMatrixFunc <> nil then
      Result := sgInvertMatrixFunc(@AData, @InvertMatrix)
    else
      Result := RESULT_ERROR;
  except
    Result := RESULT_ERROR;
  end;
end;

function sgEndWire(AContext: PsgContext; const AData: TsgWireData): Integer;
begin
  try
    if @sgEndWireFunc <> nil then
      Result := sgEndWireFunc(AContext, @AData)
    else
      Result := RESULT_ERROR;
  except
    Result := RESULT_ERROR;
  end;
end;

function sgBeginWire(AContext: PsgContext): Integer;
begin
  try
    if @sgBeginWireFunc <> nil then
      Result := sgBeginWireFunc(AContext)
    else
      Result := RESULT_ERROR;
  except
    Result := RESULT_ERROR;
  end;
end;

function sgAddConeSurface(AContext: PsgContext; const AData: TsgConeData): Integer;
begin
  try
    if @sgAddConeSurfaceFunc <> nil then
      Result := sgAddConeSurfaceFunc(AContext, @AData)
    else
      Result := RESULT_ERROR;
  except
    Result := RESULT_ERROR;
  end;
end;

function sgAddPlaneSurface(AContext: PsgContext; const AData: TsgPlaneData): Integer;
begin
  try
    if @sgAddPlaneSurfaceFunc <> nil then
      Result := sgAddPlaneSurfaceFunc(AContext, @AData)
    else
      Result := RESULT_ERROR;
  except
    Result := RESULT_ERROR;
  end;
end;

function sgAddTorusSurface(AContext: PsgContext; const AData: TsgTorusData): Integer;
begin
  try
    if @sgAddTorusSurfaceFunc <> nil then
      Result := sgAddTorusSurfaceFunc(AContext, @AData)
    else
      Result := RESULT_ERROR;
  except
    Result := RESULT_ERROR;
  end;
end;

function sgAddSphereSurface(AContext: PsgContext; const AData: TsgSphereData): Integer;
begin
  try
    if @sgAddSphereSurfaceFunc <> nil then
      Result := sgAddSphereSurfaceFunc(AContext, @AData)
    else
      Result := RESULT_ERROR;
  except
    Result := RESULT_ERROR;
  end;
end;

function sgAddSplineSurface(AContext: PsgContext; const AData: TsgSplineSurfaceData): Integer;
begin
  try
    if @sgAddSplineSurfaceFunc <> nil then
      Result := sgAddSplineSurfaceFunc(AContext, @AData)
    else
      Result := RESULT_ERROR;
  except
    Result := RESULT_ERROR;
  end;
end;

function sgAddEllipse(AContext: PsgContext; const AData: TsgEllipseData): Integer;
begin
  try
    if @sgAddEllipseFunc <> nil then
      Result := sgAddEllipseFunc(AContext, @AData)
    else
      Result := RESULT_ERROR;
  except
    Result := RESULT_ERROR;
  end;
end;

function sgAddArc(AContext: PsgContext; const AData: TsgArcData): Integer;
begin
  try
    if @sgAddArcFunc <> nil then
      Result := sgAddArcFunc(AContext, @AData)
    else
      Result := RESULT_ERROR;
  except
    Result := RESULT_ERROR;
  end;
end;

function sgAddLine(AContext: PsgContext; const AData: TsgLineData): Integer;
begin
  try
    if @sgAddLineFunc <> nil then
      Result := sgAddLineFunc(AContext, @AData)
    else
      Result := RESULT_ERROR;
  except
    Result := RESULT_ERROR;
  end;
end;

function sgAddStraight(AContext: PsgContext; const AData: TsgStraightData): Integer;
begin
  try
    if @sgAddStraightFunc <> nil then
      Result := sgAddStraightFunc(AContext, @AData)
    else
      Result := RESULT_ERROR;
  except
    Result := RESULT_ERROR;
  end;
end;

function sgAddBSpline(AContext: PsgContext; const AData: TsgBSplineData): Integer;
begin
  try
    if @sgAddBSplineFunc <> nil then
      Result := sgAddBSplineFunc(AContext, @AData)
    else
      Result := RESULT_ERROR;
  except
    Result := RESULT_ERROR;
  end;
end;

function sgInitParser(AContext: PsgContext; const AData: TsgInitParam): Integer;
begin
  try
    if @sgInitParserFunc <> nil then
      Result := sgInitParserFunc(AContext, @AData)
    else
      Result := RESULT_ERROR;
  except
    Result := RESULT_ERROR;
  end;
end;

function IsLoadMeshBuilderDll: Boolean;
begin
  Result := False;
  if sgMeshBuilderNotUsing then
    Exit;
{$IFNDEF CS_STATIC_MESHBUILDER_DLL}
  if MeshBuilderDllInst = 0 then InitMeshBuilderDll(cnstMeshBuilderDllPath);
{$ENDIF}
  if @sgInitParserFunc <> nil then
    Result := True;
end;

initialization
  LockCallMeshBuilder := False;

finalization
{$IFNDEF CS_STATIC_MESHBUILDER_DLL}
  // FreeMeshBuilderDll call was desactivated because it lead to an application crash
  // Our investigation suggests that is the fault of the OpenCascade's dll .
  //FreeMeshBuilderDll;
{$ENDIF}

end.
