ObjectARX
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Blocktablerecord size

6 REPLIES 6
Reply
Message 1 of 7
Anonymous
1239 Views, 6 Replies

Blocktablerecord size

Hello all,

I am relatively new to arx programming with C# (and to Autocad in general) and there is a problem with one of the block libraries that I have. I would like to have all of the blocks in this library place at the same size (without having to rescale them after I place them). Is there anyway that I can programmatically see and change the insertion size in a blocktablerecord so that I can make all of the blocks in my library the same size?
6 REPLIES 6
Message 2 of 7
Anonymous
in reply to: Anonymous

You can check the overal size of an AcDbBlockTableRecord by cycling its
entities and checking their extents. Add all of the extents together, and
you've got the size of the block if it is inserted with a scale of 1.

To make them all the same size, you would have to scale all of the child
entities of the containing block.

Try it out, let me know if you have problems.

-Rich


wrote in message news:5595511@discussion.autodesk.com...
Hello all,

I am relatively new to arx programming with C# (and to Autocad in general)
and there is a problem with one of the block libraries that I have. I would
like to have all of the blocks in this library place at the same size
(without having to rescale them after I place them). Is there anyway that I
can programmatically see and change the insertion size in a blocktablerecord
so that I can make all of the blocks in my library the same size?
Message 3 of 7
Anonymous
in reply to: Anonymous

This code will allow you to "normalize" symbols sizes in the current drawing.


{code}
namespace SymbolsNormalizer
{
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;

public class SymbolsNormalizer
{
///
/// Normalizes all symbols in the current drawing to have a size of 1x1.
///

[CommandMethod("normalizeSymbols")]
public static void Normalize()
{
int count = 0;
int success = 0;
using (Transaction transaction = Application.DocumentManager.MdiActiveDocument.TransactionManager.StartTransaction())
{
var blocktable = (BlockTable)transaction.GetObject(Application.DocumentManager.MdiActiveDocument.Database.BlockTableId, OpenMode.ForRead);
foreach (var blockId in blocktable)
{
var block = (BlockTableRecord)transaction.GetObject(blockId, OpenMode.ForRead);
if (block.Name.StartsWith("*") || block.IsAnonymous)
continue;
count++;
Extents3d extents = new Extents3d();
try
{
extents.AddBlockExtents(block);
}
catch (System.Exception e)
{
Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(string.Format("FAILED: {0}\n", block.Name));
continue;
}
double x = extents.MaxPoint.X - extents.MinPoint.X;
double y = extents.MaxPoint.Y - extents.MinPoint.Y;
double max = x > y ? x : y;

Matrix3d matrix = Matrix3d.Scaling(1 / max, new Point3d(0, 0, 0));

foreach (ObjectId entityId in block)
{
Entity entity = transaction.GetObject(entityId, OpenMode.ForWrite) as Entity;
if (entity != null)
entity.TransformBy(matrix);
}
success++;
}
transaction.Commit();
}

Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(string.Format("symbols successfully normalized: {0}/{1}\n", success, count));
}
}
}

{code}
Message 4 of 7
mark.electricaldesign
in reply to: Anonymous

It would be good to see an Interop COM solution I am struggling to access the BlockTableRecord of a Dynamic Block. Any pointers would be great 🙂

 

TIA

 

Mark

Message 5 of 7
tbrammer
in reply to: Anonymous

An easier approach is to create a block reference with scale 1x1x1 and determine its extents.


Thomas Brammer ● Software Developer ● imos AGLinkedIn
If an answer solves your problem please [ACCEPT SOLUTION]. Otherwise explain why not.

Message 6 of 7


@mark.electricaldesign wrote:

It would be good to see an Interop COM solution I am struggling to access the BlockTableRecord of a Dynamic Block. Any pointers would be great 🙂

 

TIA

 

Mark


Dynamic Blocks are more tricky than normally scaled blocks.

I recommend to use ArxDbg.arx (<ARXDIR>\samples\database\ARXDBG) and the commands SNOOPDB / SNOOPENTS to analyze dynamic BREFs/BTR.

Whenever you create a "dynamic BREF" an unnamed block (AcDbBlockTableRecord named "*U<n>") will be created and referenced. This block contains entities that are adjustet to the parameter set used.

 

Here is a (C++) function that I use to find out whether a BREF or BTR is dynamic. Maybe it helps you to understand the API.

 

bool isDynamicBlock(const AcDbObjectId &objId)
{
	AcDbObject	  *pObj;
	AcDbBlockReference *pBref;
	AcDbBlockTableRecord *pBTR;
	Acad::ErrorStatus es;
	AcDbObjectId blockTableRecordId;
	bool bIsDynamic = false;

	// Is objId a BREF or a BTR?
	es = acdbOpenObject(pObj, objId, AcDb::kForRead);
	if (es==Acad::eOk)
	{	
		if (pBref = AcDbBlockReference::cast(pObj))
		{
			blockTableRecordId = pBref->blockTableRecord();
			AcDbDynBlockReference dynBlockRef(pBref);
			// dynBlockRef.isDynamicBlock(); is not enough! 
			// Only returns true for direct BREF to the dynamic source-block!
			AcDbObjectId  dynBTRid = dynBlockRef.dynamicBlockTableRecord();
			if (!dynBTRid.isNull())
				bIsDynamic = AcDbDynBlockReference::isDynamicBlock(dynBTRid);
		}
		else if (pBTR = AcDbBlockTableRecord::cast(pObj))
		{
			blockTableRecordId = objId;
		}
		pObj->close();

		if (!bIsDynamic)
			bIsDynamic = AcDbDynBlockReference::isDynamicBlock(blockTableRecordId);
	}

	return bIsDynamic;
}

 

 Note that the function will return false if objId is the ID of the unnamed BTR.


Thomas Brammer ● Software Developer ● imos AGLinkedIn
If an answer solves your problem please [ACCEPT SOLUTION]. Otherwise explain why not.

Message 7 of 7

Wow! I never knew those examples existed.

Many thanks for your help.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost