How to Explode a Block
Moderators: SDS, support, admin
-
- Posts: 54
- Joined: 14 Mar 2015, 22:33
How to Explode a Block
Hi:
Can you show a code for exploding blocks.
Thanks!
Can you show a code for exploding blocks.
Thanks!
Re: How to Explode a Block
Hi,
Even I am having the same query. Can anyone please help ?
Even I am having the same query. Can anyone please help ?
Re: How to Explode a Block
Hello,
Below you will find the requested sample code.
Mikhail
Below you will find the requested sample code.
Code: Select all
interface
uses
..., CADImage, DXFConv, sgFunction, sgConsts;
...
implementation
{$R *.dfm}
procedure ExplodeInsert(ACADImage: TsgCADImage; AInsert: TsgDXFInsert);
var
I, J: Integer;
vBlockEnt: TsgDXFEntity;
vDXFInsert: TsgDXFInsert;
vDXFLine: TsgDXFLine;
vDXFLWPolyline: TsgDXFPolyline;
vDXFCircle: TsgDXFCircle;
vMatrix: TFMatrix;
vPoint, vScale, vExtrusion: TFPoint;
vAngle: Double;
begin
vMatrix := AInsert.GetMatrix;
// Iterate through entities in the block
for I := 0 to AInsert.Block.Count - 1 do
begin
vBlockEnt := AInsert.Block.Entities[I];
case vBlockEnt.EntType of
ceLine: // LINE entity
begin
// Create a copy of the entity which is inside the block
vDXFLine := TsgDXFLine.Create;
vDXFLine.AssignEntity(vBlockEnt);
// Multiply coordinates of the created entity by the transformation matrix
vDXFLine.Point := FPointXMat(vDXFLine.Point, vMatrix);
vDXFLine.Point1 := FPointXMat(vDXFLine.Point1, vMatrix);
ACADImage.Converter.Loads(vDXFLine);
ACADImage.CurrentLayout.AddEntity(vDXFLine);
end;
ceLWPolyline: // LWPOLYLINE entity
begin
vDXFLWPolyline := TsgDXFLWPolyline.Create;
vDXFLWPolyline.AssignEntity(vBlockEnt);
for J := 0 to vDXFLWPolyline.Count - 1 do
vDXFLWPolyline.Vertexes[J].Point := FPointXMat(vDXFLWPolyline.Vertexes[J].Point, vMatrix);
ACADImage.Converter.Loads(vDXFLWPolyline);
ACADImage.CurrentLayout.AddEntity(vDXFLWPolyline);
end;
ceCircle: // CIRCLE entity
begin
vDXFCircle := TsgDXFCircle.Create;
vDXFCircle.AssignEntity(vBlockEnt);
vDXFCircle.Point := FPointXMat(vDXFCircle.Point, vMatrix);
vDXFCircle.Radius := DistanceFVector(AffineTransformPoint(MakeFPoint(0, vDXFCircle.Radius, 0), vMatrix));
ACADImage.Converter.Loads(vDXFCircle);
ACADImage.CurrentLayout.AddEntity(vDXFCircle);
end;
ceInsert: // nested INSERT entity
begin
//ExplodeInsert(ACADImage, vSrcEnt as TsgDXFInsert);
vDXFInsert := TsgDXFInsert.Create;
vDXFInsert.AssignEntity(vBlockEnt);
ExtractMatrixParams(FMatXMat(TsgDXFInsert(vBlockEnt).GetMatrix, vMatrix), vPoint, vScale, vExtrusion, vAngle);
vDXFInsert.Point := vPoint;
vDXFInsert.Scale := vScale;
vDXFInsert.Extrusion := vExtrusion;
vDXFInsert.Angle := vAngle;
ACADImage.Converter.Loads(vDXFInsert);
ACADImage.CurrentLayout.AddEntity(vDXFInsert);
end;
end;
end;
// Delete the INSERT after exploding
ACADImage.Converter.RemoveEntity(AInsert, True);
// Recalculate the CAD image extents
ACADImage.GetExtents();
end;
Technical Support E-mail: support@cadsofttools.com
Chat support on Skype: cadsofttools.support
Chat support on Skype: cadsofttools.support
Re: How to Explode a Block
How to do the same for Text and MText ??
What I really want is to have the coordinates of all the strokes within TEXT and MText..
Thank you !!
Ax
What I really want is to have the coordinates of all the strokes within TEXT and MText..
Thank you !!
Ax
Re: How to Explode a Block
Hello,
You can convert each line of TsgDXFMText entity to a single-line TsgDXFText entity using the following code.
Mikhail
You can convert each line of TsgDXFMText entity to a single-line TsgDXFText entity using the following code.
Code: Select all
procedure ExplodeInsert(ACADImage: TsgCADImage; AInsert: TsgDXFInsert);
var
I, J: Integer;
vBlockEnt: TsgDXFEntity;
vDXFInsert: TsgDXFInsert;
vDXFLine: TsgDXFLine;
vDXFLWPolyline: TsgDXFPolyline;
vDXFCircle: TsgDXFCircle;
vDXFText: TsgDXFText;
vDXFMText: TsgDXFMText;
vMatrix: TFMatrix;
vPoint, vScale, vExtrusion: TFPoint;
vAngle: Double;
begin
vMatrix := AInsert.GetMatrix;
// Iterate through entities in the block
for I := 0 to AInsert.Block.Count - 1 do
begin
vBlockEnt := AInsert.Block.Entities[I];
case vBlockEnt.EntType of
ceLine: // LINE entity
begin
// Create a copy of the entity which is inside the block
vDXFLine := TsgDXFLine.Create;
vDXFLine.AssignEntity(vBlockEnt);
// Multiply coordinates of the created entity by the transformation matrix
vDXFLine.Point := FPointXMat(vDXFLine.Point, vMatrix);
vDXFLine.Point1 := FPointXMat(vDXFLine.Point1, vMatrix);
ACADImage.Converter.Loads(vDXFLine);
ACADImage.CurrentLayout.AddEntity(vDXFLine);
end;
ceText: // TEXT entity
begin
vDXFText := TsgDXFText.Create;
vDXFText.AssignEntity(vBlockEnt);
if vDXFText.InsideMText then
vDXFText.Point1 := FPointXMat(AInsert.Point, FMatByTranslate(vDXFText.Point1))
else
vDXFText.Point := FPointXMat(vDXFText.Point, vMatrix);
ACADImage.Converter.Loads(vDXFText);
ACADImage.CurrentLayout.AddEntity(vDXFText);
end;
ceLWPolyline: // LWPOLYLINE entity
begin
vDXFLWPolyline := TsgDXFLWPolyline.Create;
vDXFLWPolyline.AssignEntity(vBlockEnt);
for J := 0 to vDXFLWPolyline.Count - 1 do
vDXFLWPolyline.Vertexes[J].Point := FPointXMat(vDXFLWPolyline.Vertexes[J].Point, vMatrix);
ACADImage.Converter.Loads(vDXFLWPolyline);
ACADImage.CurrentLayout.AddEntity(vDXFLWPolyline);
end;
ceCircle: // CIRCLE entity
begin
vDXFCircle := TsgDXFCircle.Create;
vDXFCircle.AssignEntity(vBlockEnt);
vDXFCircle.Point := FPointXMat(vDXFCircle.Point, vMatrix);
vDXFCircle.Radius := DistanceFVector(AffineTransformPoint(MakeFPoint(0, vDXFCircle.Radius, 0), vMatrix));
ACADImage.Converter.Loads(vDXFCircle);
ACADImage.CurrentLayout.AddEntity(vDXFCircle);
end;
ceInsert: // nested INSERT entity
begin
vDXFInsert := TsgDXFInsert.Create;
vDXFInsert.AssignEntity(vBlockEnt);
ExtractMatrixParams(FMatXMat(TsgDXFInsert(vBlockEnt).GetMatrix, vMatrix), vPoint, vScale, vExtrusion, vAngle);
vDXFInsert.Point := vPoint;
vDXFInsert.Scale := vScale;
vDXFInsert.Extrusion := vExtrusion;
vDXFInsert.Angle := vAngle;
ACADImage.Converter.Loads(vDXFInsert);
ACADImage.CurrentLayout.AddEntity(vDXFInsert);
end;
ceMText: // MTEXT entity
begin
vDXFMText := vBlockEnt as TsgDXFMText;
// Extract TEXT entities from the MTEXT
ExplodeInsert(ACADImage, vDXFMText);
end;
end;
end;
// Delete the INSERT after exploding
ACADImage.Converter.RemoveEntity(AInsert, True);
// Recalculate the CAD image extents
ACADImage.GetExtents();
end;
Technical Support E-mail: support@cadsofttools.com
Chat support on Skype: cadsofttools.support
Chat support on Skype: cadsofttools.support
Re: How to Explode a Block
Mikhail,
Excellent and very illustrative code.
My additional question is Is it possible to get the actual Text strokes, as polylines without the use of the font file. ?
I saw a function called GetTextPolylines .... somewhere .. should it be it ?
What Ia am doing is to convert each entity to a very different plane (actually two simultaneous planes).. that is what I was wondering if I could extract the very primitive text strokes.
Other way to do it is to read the shx file (which I do not know how ... at the moment)
Thanks for your patience
Alex
Excellent and very illustrative code.
My additional question is Is it possible to get the actual Text strokes, as polylines without the use of the font file. ?
I saw a function called GetTextPolylines .... somewhere .. should it be it ?
What Ia am doing is to convert each entity to a very different plane (actually two simultaneous planes).. that is what I was wondering if I could extract the very primitive text strokes.
Other way to do it is to read the shx file (which I do not know how ... at the moment)
Thanks for your patience
Alex
Re: How to Explode a Block
Hello Alex,
You are right. There is a TsgDXFConverter.GetTextPolylines function which converts a TsgDXFText object (AText) into a TList of lists of points (AList):
To create polylines from the TList received with the use of this function, use the following procedure:
To free the TList of lists, please use sgConsts.FreeRecordListOfList procedure.
Mikhail
You are right. There is a TsgDXFConverter.GetTextPolylines function which converts a TsgDXFText object (AText) into a TList of lists of points (AList):
Code: Select all
function TsgDXFConverter.GetTextPolylines(const AText: TsgDXFText; const AList: TList): Integer;
Code: Select all
procedure CreatePolylines(ACADImage: TsgCADImage; const AList: TList);
var
I, J: Integer;
vPoly: TsgDXFPolyline;
vVertex: TsgDXFVertex;
vContour: TList;
begin
for I := 0 to AList.Count - 1 do
begin
vPoly := TsgDXFPolyline.Create();
vPoly.Color := clRed;
vPoly.Closed := False;
vContour := AList[I];
for J := 0 to vContour.Count - 1 do
begin
vVertex := TsgDXFVertex.Create();
vVertex.Point := TFPoint(vContour[J]^);
vPoly.AddEntity(vVertex);
end;
ACADImage.Converter.Loads(vPoly);
ACADImage.CurrentLayout.AddEntity(vPoly);
end;
ACADImage.GetExtents();
vContour.Free;
end;
Mikhail
Technical Support E-mail: support@cadsofttools.com
Chat support on Skype: cadsofttools.support
Chat support on Skype: cadsofttools.support
Re: How to Explode a Block
Thank you Mikhail,
Implemented and working fine !!
Implemented and working fine !!