Error when save to dwg format with blocks containing 3dFaces

Discuss and ask questions about CAD VCL (Delphi and C++ Builder).

Moderators: admin, support, SDS

Post Reply
FieldConsult
Posts: 54
Joined: 14 Mar 2015, 22:33

Error when save to dwg format with blocks containing 3dFaces

Post by FieldConsult » 02 Jun 2018, 21:29

Hi,

I have encountered a severe error when trying to export an image containing blocks with 3dFaces to the dwg or dxf format.
The error in AutoCAD, when trying to open the file is:
The following error was encountered while reading
in INSERT starting at line 877370:
Class separator for class AcDbEntity expected
Invalid or incomplete DXF input -- drawing discarded.
Any idea how to fix it?.

Maybe you can show a correct code to create a drawing with numerous blocks that contains several 3dFace objects and can be exported to the dwg format?
Attachments
2018-06-02_20-19-27.png
AutoCAD Error Image
2018-06-02_20-19-27.png (130.01 KiB) Viewed 13092 times

FieldConsult
Posts: 54
Joined: 14 Mar 2015, 22:33

Re: Error when save to dwg format with blocks containing 3dF

Post by FieldConsult » 03 Jun 2018, 20:47

This problem is coming form long time ago, I can see another user with the same problem (Export DXF DWG topic, Do you create DXF and DWG files from scratch or resave the existing files?).

I have tried both alternatives, loading an empty file and creating a new one in memory, in both cases the problem is the same.

I think what is needed is the publication of what entities is really capable of saving with CADExport?

Thaks!

support
Posts: 2930
Joined: 30 Mar 2005, 11:36
Contact:

Re: Error when save to dwg format with blocks containing 3dF

Post by support » 04 Jun 2018, 17:46

Hello,

CADExport is the ancestor class of all export classes, you shouldn't use it for saving to DWG/DXF.
Please post a code which will allow to reproduce the problem.

Mikhail
Technical Support E-mail: support@cadsofttools.com
Chat support on Skype: cadsofttools.support

FieldConsult
Posts: 54
Joined: 14 Mar 2015, 22:33

Re: Error when save to dwg format with blocks containing 3dF

Post by FieldConsult » 10 Jun 2018, 16:15

The Code Iuse is:

Code: Select all

function MakeSingleDTMFaces(pt1, pt2, pt3: TFPoint; blockName: string = 'Block'): TsgDXF3dFace;
begin
  Result:= TsgDXF3dFace.Create;
  Result.Point:= pt1;
  Result.Point1:= pt2;
  Result.Point2:= pt3;
  Result.Point3:= pt3;
  Result.Layer:= DwgCADImage.Converter.LayerByName(blockName);
end;

procedure Create3DIfcFace(IfcObject: TIfcObjectStruct);
var
  mesh3dFace: TsgDXF3dFace;
  P1: TFPoint;

  I, J: Integer;
  Step: Integer;
  vCount: Integer;
  pList: TList<TFPoint>;

  vBlock: TsgDXFBlock;
  vInsert: TsgDXFInsert;
  layerName: string;
  bColor: TColor;
  ifcName: string;
  aColor: TAlphaColorRec;

  R,G,B,A: Int64;
begin
  pList:= TList<TFPoint>.Create;
  vBlock := TsgDXFBlock.Create;

  ifcName:= MakeValidIdent(IfcObject.Name);
  try
    layerName:= IfcObject.IfcType + '-' + ifcName;
    vBlock.Name := ifcName + '-.-' + IntToStr(IfcObject.Instance);
    vBlock.Layer := DwgCADImage.Converter.LayerByName(layerName);
    vBlock.Flags := 2;

    // Add vertices
    Step:= 0;
    vCount:= Length(IfcObject.Vertices) div 2;
    for I := 1 to (vCount div 3) do
      begin
        P1:= MakeFPoint(IfcObject.Vertices[step], IfcObject.Vertices[step + 1], IfcObject.Vertices[step + 2]);
        pList.Add(P1);
        step:= step + 6;
      end;

    try
      begin
        Step:= 0;
        vCount:= Length(IfcObject.IndicesForFaces);
        for I := 1 to (vCount div 3) do
          begin
            mesh3dFace:= MakeSingleDTMFaces(pList[IfcObject.IndicesForFaces[step]],
                                            pList[IfcObject.IndicesForFaces[step + 1]],
                                            pList[IfcObject.IndicesForFaces[step + 2]],
                                            layerName);
            if Assigned(DwgCADImage.Converter.OnCreate) then DwgCADImage.Converter.OnCreate(mesh3dFace);
            DwgCADImage.Converter.Loads(mesh3dFace);
            vBlock.AddEntity(mesh3dFace);
            step:= step + 3;
          end;
      end;

      if Assigned(DwgCADImage.Converter.OnCreate) then DwgCADImage.Converter.OnCreate(vBlock);
      DwgCADImage.Converter.Loads(vBlock);
      DwgCADImage.Converter.Sections[csBlocks].AddEntity(vBlock);

      vInsert := TsgDXFInsert.Create;
      vInsert.Handle:= IfcObject.Instance;
      vInsert.Block := vBlock;
      vInsert.Point := MakeFPoint(0,0,0);
      vInsert.Scale := MakeFPoint(1, 1, 1);
      vInsert.Color:= clByLayer;
      vInsert.Layer := DwgCADImage.Converter.LayerByName(layerName);

      AddEntityToImage(DwgCADImage, vInsert);
      FBlocks.Add(IfcObject.Instance, vInsert);

      bColor:= IfcObject.IfcColorAmbient;

      DwgCADImage.Converter.LayerByName(layerName).Color:= bColor;
      DwgCADImage.Converter.LayerByName(layerName).Visible:= Visible;
    finally
      FreeAndNil(pList);
    end;
  except on E: Exception do

  end;
end;

I also use the procedure indicated in the examples of the library, using the exporter corresponding to the selected extension. TsgCADtoDWG and TsgCADtoDXF. But both show the same error when opening with AutoCAD.

When I use blocks with attributes I do not have any problems and I follow the same procedure, so I think the problem is in the configuration of the 3DFaces

Maybe I forgot some flag or something else?

Thank!!!

support
Posts: 2930
Joined: 30 Mar 2005, 11:36
Contact:

Re: Error when save to dwg format with blocks containing 3dF

Post by support » 18 Jun 2018, 23:45

Hello,

Please try the code below, it creates a valid DWG file containing three 3DFACE objects in a block.

Code: Select all

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, CADImage, DXFConv, CADToDWG, sgConsts, Generics.Collections, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
    FCADImage: TsgCADImage;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure AddEntityToImage(ATargetImage: TsgCADImage; AEntity: TsgDXFEntity);
begin
  if not Assigned(ATargetImage) then Exit;
  ATargetImage.CurrentLayout.AddEntity(AEntity);
  if Assigned(ATargetImage.Converter.OnCreate) then
    ATargetImage.Converter.OnCreate(AEntity);
  ATargetImage.Converter.Loads(AEntity);
  ATargetImage.GetExtents;
end;

procedure SaveToDWG(ACADImage: TsgCADImage; AFileName: string);
var
  vCADtoDWG: TsgCADtoDWG;
begin
  if not Assigned(ACADImage) then Exit;
  vCADtoDWG := TsgCADtoDWG.Create(ACADImage);
  try
    vCADtoDWG.SaveToFile(AFileName);
  finally
    vCADtoDWG.Free;
  end;
end;

function MakeSingleDTMFaces(ACADImage: TsgCADImage; pt1, pt2, pt3: TFPoint; blockName: string = 'Block'): TsgDXF3dFace;
begin
  Result:= TsgDXF3dFace.Create;
  Result.Point := pt1;
  Result.Point1 := pt2;
  Result.Point2 := pt3;
  Result.Point3 := pt3;
  Result.Layer := ACADImage.Converter.LayerByName(blockName);
end;

procedure Create3DIfcFace(ACADImage: TsgCADImage);
var
  mesh3dFace: TsgDXF3dFace;
  P1: TFPoint;

  I: Integer;
  step: Integer;
  vCount: Integer;
  pList: TList<TFPoint>;

  vBlock: TsgDXFBlock;
  vInsert: TsgDXFInsert;
  layerName: string;
begin
  pList := TList<TFPoint>.Create;
  vBlock := TsgDXFBlock.Create;

  layerName := '3dFaces';
  vBlock.Name := '3dFacesBlock';
  vBlock.Flags := 2;

  P1 := MakeFPoint(0, 0, 0);
  pList.Add(P1);
  P1 := MakeFPoint(75, 50, 50);
  pList.Add(P1);
  P1 := MakeFPoint(150, 0, 0);
  pList.Add(P1);
  P1 := MakeFPoint(0, 0, 0);
  pList.Add(P1);
  P1 := MakeFPoint(75, 140, 0);
  pList.Add(P1);
  P1 := MakeFPoint(75, 50, 50);
  pList.Add(P1);
  P1 := MakeFPoint(75, 50, 50);
  pList.Add(P1);
  P1 := MakeFPoint(75, 140, 0);
  pList.Add(P1);
  P1 := MakeFPoint(150, 0, 0);
  pList.Add(P1);
  try
    step := 0;
    vCount := pList.Count;
    for I := 1 to (vCount div 3) do
    begin
      mesh3dFace := MakeSingleDTMFaces(ACADImage, pList[step],
                                                  pList[step + 1],
                                                  pList[step + 2],
                                                  layerName);
      if Assigned(ACADImage.Converter.OnCreate) then
        ACADImage.Converter.OnCreate(mesh3dFace);
      ACADImage.Converter.Loads(mesh3dFace);
      vBlock.AddEntity(mesh3dFace);
      step := step + 3;
    end;
    if Assigned(ACADImage.Converter.OnCreate) then
      ACADImage.Converter.OnCreate(vBlock);
    ACADImage.Converter.Loads(vBlock);
    ACADImage.Converter.Sections[csBlocks].AddEntity(vBlock);

    vInsert := TsgDXFInsert.Create;
    vInsert.Block := vBlock;
    vInsert.Point := MakeFPoint(0, 0, 0);
    vInsert.Scale := MakeFPoint(1, 1, 1);
    vInsert.Color := clByLayer;
    vInsert.Layer := ACADImage.Converter.LayerByName(layerName);
    AddEntityToImage(ACADImage, vInsert);
  finally
    FreeAndNil(pList);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  FCADImage := TsgCADImage.Create;
  FCADImage.Converter.InitializeSectionsBegin;
  FCADImage.Converter.InitializeSectionsEnd;
  FCADImage.CurrentLayout := FCADImage.Layouts[0];
  Create3DIfcFace(FCADImage);
  SaveToDWG(FCADImage, ExtractFilePath(Application.ExeName) + '3dFaces.dwg');
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  FreeAndNil(FCADImage);
end;

end.
Mikhail
Technical Support E-mail: support@cadsofttools.com
Chat support on Skype: cadsofttools.support

Post Reply