{************************************************************}
{                   Delphi VCL Extensions                    }
{                                                            }
{                    B-rep images clases                     }
{                                                            }
{      Copyright (c) 2002-2014 SoftGold software company     }
{                                                            }
{************************************************************}

{$I SGDXF.INC}
unit sgSatImage;

interface

uses Windows, SysUtils, Classes, Graphics, DXFConv, CADImage,
  sgFunction, sgConsts, Math, sgLines, sgLists, sgMeshBuilderWrapper,
  sgBrepConverter
  {$IFDEF SGDEL_2009}
  ,AnsiStrings
  {$ENDIF}
  ;

type
  TsgCommonBrepImageError = class(Exception);

  TsgCommonBrepImage = class(TsgVectorImage)
  private
    FStopLoad: Boolean;
    FNeed2DViewByDefault: Boolean;
    function GetNeed2DViewByDefault: Boolean;
  protected
    procedure DoLoad(const Stream: TStream; const FileName: string);
    function GetDefaultView: TsgDefaultView; override;
    procedure LoadBrep(const Stream: TStream; const ALayer: TsgDXFLayer;
      const FileName: string); virtual;
  public
    constructor Create; override;
    procedure StopLoading; override;
  end;

  TsgSATImage = class(TsgCommonBrepImage)
  protected
    procedure LoadBrep(const Stream: TStream; const ALayer: TsgDXFLayer;
      const FileName: string); override;
  public
    procedure LoadFromStream(S: TStream); override;
  end;

  TsgBrepImage = class(TsgCommonBrepImage)
  private
    FBrep: TsgBrepGroup;
    FBrepCreator: TsgCreatorEntityBase;
  protected
    function CreateBrepGroup: TsgDXFEntity;
    function GetBrepGroupClass: TClass; virtual;
    function Get3DFileType: Integer; virtual;
    procedure LoadBrep(const Stream: TStream; const ALayer: TsgDXFLayer;
      const FileName: string); override;
  public
     procedure LoadFromFile(const FileName: string); override;
     procedure LoadFromStream(S: TStream); override;
  end;

  TsgIGESVectorFile = class(TsgBrepImage)
  protected
    function GetBrepGroupClass: TClass; override;
    function Get3DFileType: Integer; override;
  end;

  TsgSTEPVectorFile = class(TsgBrepImage)
  protected
    function GetBrepGroupClass: TClass; override;
    function Get3DFileType: Integer; override;
  end;

  TsgBrepVectorFile = class(TsgBrepImage)
  protected
    function GetBrepGroupClass: TClass; override;
    function Get3DFileType: Integer; override;
  end;

const
  sSATImage = 'SAT image';

implementation

const
  cnst3dFile = '';

type
  TsgDXFConverterAccess = class(TsgDXFConverter);
  TsgDXFEntityAccess = class(TsgDXFEntity);

{ TsgSATImage }

procedure TsgSATImage.LoadFromStream(S: TStream);
begin
  inherited LoadFromStream(S);
  DoLoad(S, '');
end;

procedure TsgSATImage.LoadBrep(const Stream: TStream; const ALayer: TsgDXFLayer;
  const FileName: string);
var
  vAcis: TsgDXFACISEntity;
begin
  vAcis := TsgDXF3dSolid.Create;
  vAcis.LoadFromStream(Stream);
  vAcis.Delimiter := ' ';
  Converter.DoCreate(vAcis);
  Converter.Loads(vAcis);
  TsgDXFConverterAccess(Converter).Layouts[0].AddEntity(vAcis);
end;

{ TsgBrepImage }

function CallBackStop(Parser: Pointer; ACurrent, AMaxCount: Integer):Integer; cdecl;
begin
  TsgCommonBrepImage(Parser).DoOnProgress(psRunning,ACurrent,
    AMaxCount);
  Result := 0;
  if (TsgCommonBrepImage(Parser).FStopLoad = True) then
    Result := 1;
end;

procedure TsgBrepImage.LoadBrep(const Stream: TStream; const ALayer: TsgDXFLayer;
  const FileName: string);
var
  vInitData: TsgInitMeshBuilderData;
  vParams: PsgParamTriangle;
begin
  FBrep := TsgBrepGroup(CreateBrepGroup);
  FBrep.FileName := FileName;
  FBrepCreator := TsgCreatorEntityBase.Create(Converter, FBrep);
  try
    ZeroMemory(@vInitData, Sizeof(vInitData));
    vInitData.File3DType := Get3DFileType;
    vInitData.File3DName := PAnsiChar(AnsiString(FileName));
    vInitData.DrawWireFunc := @CallBackDrawWireVertexDraw;
    vInitData.DrawISOFunc := @CallBackDrawISOVertexDraw;
    vInitData.DrawTestFunc := @CallBackDrawTestVertexDraw;
    vInitData.StopFunc := @CallBackStop;
    vInitData.Self := Pointer(Self);
    vInitData.Creator := Pointer(FBrepCreator);

    New(vParams);
    try
      ZeroMemory(vParams, SizeOf(vParams));
      vParams^.ASelf := vInitData.Creator;
      vInitData.BeginSegment := @BeginSegment;
      vInitData.EndSegment := @EndSegment;
      vInitData.MeshParam := vParams;
      FBrep.GetMeshBrep(vInitData, cnstDeviationCoefficientDefault);
    finally
      Dispose(vParams);
    end;
  finally
    FBrepCreator.Free;
  end;
  FBrep.Layer := Converter.LayerByName('0');
  Converter.LoadsGroup(FBrep);
  Converter.DoCreate(FBrep);
  Converter.Loads(FBrep);
  Converter.Layouts[0].AddEntity(FBrep);
end;

procedure TsgBrepImage.LoadFromFile(const FileName: string);
begin
  inherited LoadFromFile(FileName);
  DoLoad(nil, FileName);
end;

procedure TsgBrepImage.LoadFromStream(S: TStream);
begin
  inherited;
end;

function TsgBrepImage.CreateBrepGroup: TsgDXFEntity;
begin
  Result := TsgDXFEntityClass(GetBrepGroupClass).Create;
  TsgDXFEntityAccess(Result).SetConverter(Converter);
end;

function TsgBrepImage.Get3DFileType: Integer;
begin
  Result := -1;
end;

function TsgBrepImage.GetBrepGroupClass: TClass;
begin
  Result := TsgBrepGroup;
end;

{ TsgIGESVectorFile }

function TsgIGESVectorFile.Get3DFileType: Integer;
begin
  Result := 0;
end;

function TsgIGESVectorFile.GetBrepGroupClass: TClass;
begin
  Result := TsgBrepIges;
end;

{ TsgSTEPVectorFile }

function TsgSTEPVectorFile.Get3DFileType: Integer;
begin
  Result := 1;
end;

function TsgSTEPVectorFile.GetBrepGroupClass: TClass;
begin
  Result := TsgBrepStep;
end;

{ TsgCommonBrepImage }

constructor TsgCommonBrepImage.Create;
begin
  inherited Create;
  ShowPlotForModel := False;
  FNeed2DViewByDefault := False;
end;

procedure TsgCommonBrepImage.DoLoad(const Stream: TStream; const FileName: string);
var
  vImage: TsgCADImage;
  vLayer: TsgDXFLayer;
begin
  if not IsLoadMeshBuilderDll then
    raise TsgCommonBrepImageError.Create(cnstMeshBuilderDLLError);
  vImage := Loading;
  if vImage <> nil then
    vImage.Converter.StopLoading;
  Loading := Self;
  DoOnProgress(psStarting, 1, 100);
  try
    TsgDXFConverterAccess(Converter).SetLoading(True, nil);
    GenerateLineTypesEx(Converter, cnst3dFile, False, True);
    CurrentLayout := TsgDXFConverterAccess(Converter).Layouts[0];
    //SetHandleForEntity(CurrentLayout);
    vLayer := Converter.LayerByName('0');
    vLayer.ColorCAD := ConvertARGBToColorCAD(clGray);
    DoOnProgress(psRunning, 1, 100);
    LoadBrep(Stream, vLayer, FileName);
    GetExtents;
    Set3DRotDef(Converter.Layouts[0].Box, FNeed2DViewByDefault);
    SetDefaultPlotSettings;
  finally
    TsgDXFConverterAccess(Converter).SetLoading(False, nil);
    Loading := nil;
  end;
  DoOnProgress(psEnding,100, 100);
end;

function TsgCommonBrepImage.GetDefaultView: TsgDefaultView;
begin
  if GetNeed2DViewByDefault then
    Result := df2D
  else
    Result := df3D;
end;

function TsgCommonBrepImage.GetNeed2DViewByDefault: Boolean;
begin
  Result := FNeed2DViewByDefault;
end;

procedure TsgCommonBrepImage.LoadBrep(const Stream: TStream;
  const ALayer: TsgDXFLayer; const FileName: string);
begin
end;

procedure TsgCommonBrepImage.StopLoading;
begin
  inherited StopLoading;
  FStopLoad := True;
end;

{ TsgBrepVectorFile }

function TsgBrepVectorFile.Get3DFileType: Integer;
begin
  Result := 2;
end;

function TsgBrepVectorFile.GetBrepGroupClass: TClass;
begin
  Result := TsgBrepBrep;
end;

initialization
  TPicture.RegisterFileFormat('sat', sSATImage, TsgSATImage);
  TPicture.RegisterFileFormat('iges', cnstDescrIGES, TsgIGESVectorFile);
  TPicture.RegisterFileFormat('igs', cnstDescrIGES, TsgIGESVectorFile);
  TPicture.RegisterFileFormat('step', cnstDescrSTEP, TsgSTEPVectorFile);
  TPicture.RegisterFileFormat('stp', cnstDescrSTEP, TsgSTEPVectorFile);
  TPicture.RegisterFileFormat('brep', cnstDescrBrep, TsgBrepVectorFile);

finalization
  TPicture.UnRegisterGraphicClass(TsgSATImage);
  TPicture.UnRegisterGraphicClass(TsgIGESVectorFile);
  TPicture.UnRegisterGraphicClass(TsgSTEPVectorFile);

end.
