Page 1 of 1
Error when save to dwg format with blocks containing 3dFaces
Posted: 02 Jun 2018, 21:29
by FieldConsult
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?
Re: Error when save to dwg format with blocks containing 3dF
Posted: 03 Jun 2018, 20:47
by FieldConsult
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!
Re: Error when save to dwg format with blocks containing 3dF
Posted: 04 Jun 2018, 17:46
by support
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
Re: Error when save to dwg format with blocks containing 3dF
Posted: 10 Jun 2018, 16:15
by FieldConsult
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!!!
Re: Error when save to dwg format with blocks containing 3dF
Posted: 18 Jun 2018, 23:45
by support
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