Hello forum,
I am trying to scale the dwg in a horizontal and vertical directions with different scales.
Original dimensions are in image below
Instead, I want dimensions as 14'-0" horizontal and 3'-1 1/16" vertically.
I achieved this manually converting this geometry to block and then used scale command with two basepoints.
I want to achieve this using c# api but didn't get a proper way.
Please guide me if there is any way to achieve this.
Thank you.
Solved! Go to Solution.
Solved by _gile. Go to Solution.
Hi,
I have very recently started dipping my toes into .NET / C# environments, so I will not be able to write a code. But, most likely weapon you are looking for is Matrix3D class available under Autodesk.AutoCAD.Geometry Imports for .NET (or Using for C#) platform. Once you set your scaling parameters in the matrix, apply that matrix to your entity (or entities) using TransformBy method and you will see your results.
The syntax would be
MyObject.TransformBy(TransformMatrix)
Hope I will be able to write a code for you in near future.
Nimish
PS: See the sample code I pasted from AutoCAD documentation available on Autodesk website.
http://docs.autodesk.com/ACD/2010/ENU/AutoCAD%20.NET%20Developer%27s%20Guide/index.html
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
[CommandMethod("ScaleObject")]
public static void ScaleObject()
{
// Get the current document and database
Document acDoc = Application.DocumentManager.MdiActiveDocument;
Database acCurDb = acDoc.Database;
// Start a transaction
using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
{
// Open the Block table for read
BlockTable acBlkTbl;
acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId,OpenMode.ForRead) as BlockTable;
// Open the Block table record Model space for write
BlockTableRecord acBlkTblRec;
acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace],OpenMode.ForWrite) as BlockTableRecord;
// Create a lightweight polyline
Polyline acPoly = new Polyline();
acPoly.SetDatabaseDefaults();
acPoly.AddVertexAt(0, new Point2d(1, 2), 0, 0, 0);
acPoly.AddVertexAt(1, new Point2d(1, 3), 0, 0, 0);
acPoly.AddVertexAt(2, new Point2d(2, 3), 0, 0, 0);
acPoly.AddVertexAt(3, new Point2d(3, 3), 0, 0, 0);
acPoly.AddVertexAt(4, new Point2d(4, 4), 0, 0, 0);
acPoly.AddVertexAt(5, new Point2d(4, 2), 0, 0, 0);
// Close the polyline
acPoly.Closed = true;
// Reduce the object by a factor of 0.5
// using a base point of (4,4.25,0)
acPoly.TransformBy(Matrix3d.Scaling(0.5, new Point3d(4, 4.25, 0)));
// Add the new object to the block table record and the transaction
acBlkTblRec.AppendEntity(acPoly);
acTrans.AddNewlyCreatedDBObject(acPoly, true);
// Save the new objects to the database
acTrans.Commit();
}
}
Hi,
Here's a quick and dirty example:
[CommandMethod("UNUNIFORMSCALE")]
public static void UnUniformScaleEntities()
{
var doc = Application.DocumentManager.MdiActiveDocument;
var db = doc.Database;
var ed = doc.Editor;
var pso = new PromptSelectionOptions();
pso.MessageForAdding ="\nSelect entities to scale: ";
var psr = ed.GetSelection();
if (psr.Status != PromptStatus.OK)
return;
var selection = psr.Value;
var ppr = ed.GetPoint("\nSpecify the base point: ");
if (ppr.Status != PromptStatus.OK)
return;
var basePoint = ppr.Value.TransformBy(ed.CurrentUserCoordinateSystem);
var pdo = new PromptDoubleOptions("\nEnter the X scale factor: ");
var pdr = ed.GetDouble(pdo);
if (pdr.Status != PromptStatus.OK)
return;
double xScale = pdr.Value;
pdo.Message = "\nEnter the Y scale factor: ";
pdr = ed.GetDouble(pdo);
if (pdr.Status != PromptStatus.OK)
return;
double yScale = pdr.Value;
using (var tr = db.TransactionManager.StartTransaction())
{
var bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForWrite);
int i = 1;
string bName, prefix = "TEMP_";
do
{
bName = prefix + i++;
} while (bt.Has(bName));
var ids = new ObjectIdCollection(selection.GetObjectIds());
var btr = new BlockTableRecord();
btr.Name = bName;
var btrId = bt.Add(btr);
tr.AddNewlyCreatedDBObject(btr, true);
var mapping = new IdMapping();
db.DeepCloneObjects(ids, btrId, mapping, false);
var displacement = Matrix3d.Displacement(basePoint.GetAsVector().Negate());
foreach (ObjectId id in ids)
{
if (mapping[id].IsCloned)
{
var entity = (Entity)tr.GetObject(mapping[id].Value, OpenMode.ForWrite);
entity.TransformBy(displacement);
entity = (Entity)tr.GetObject(id, OpenMode.ForWrite);
entity.Erase();
}
}
var br = new BlockReference(basePoint, btrId);
br.ScaleFactors = new Scale3d(xScale, yScale, 1.0);
var cSpace = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
cSpace.AppendEntity(br);
tr.AddNewlyCreatedDBObject(br, true);
br.ExplodeToOwnerSpace();
br.Erase();
btr.Erase();
tr.Commit();
}
}
Thank you _gile for your reply and code.
I have modified your code a bit but it didn't give me a scaled block reference.
I have only one block reference in my drawing.
Below is my code and attaching dwg for reference.
private void UnUniformScaleEntities()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
Point3d point = new Point3d(2.555, 8.40666666666667, 0);
Point3d basePoint = point.TransformBy(ed.CurrentUserCoordinateSystem);
double xScale = 14.0;
double yScale = 4.5;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForWrite);
ObjectIdCollection ids = new ObjectIdCollection();
foreach (ObjectId acBtrObjId in bt)
{
BlockTableRecord btRecord = (BlockTableRecord)acBtrObjId.GetObject(OpenMode.ForWrite);
ids = btRecord.GetBlockReferenceIds(true, true);
if (ids.Count > 0)
break;
}
int i = 1;
string bName, prefix = "TEMP_";
do
{
bName = prefix + i++;
} while (bt.Has(bName));
BlockTableRecord btr = new BlockTableRecord();
btr.Name = bName;
ObjectId btrId = bt.Add(btr);
tr.AddNewlyCreatedDBObject(btr, true);
IdMapping mapping = new IdMapping();
db.DeepCloneObjects(ids, btrId, mapping, false);
Matrix3d displacement = Matrix3d.Displacement(basePoint.GetAsVector().Negate());
foreach (ObjectId id in ids)
{
if (mapping[id].IsCloned)
{
Entity entity = (Entity)tr.GetObject(mapping[id].Value, OpenMode.ForWrite);
entity.TransformBy(displacement);
entity = (Entity)tr.GetObject(id, OpenMode.ForWrite);
entity.Erase();
}
}
BlockReference br = new BlockReference(basePoint, btrId);
br.ScaleFactors = new Scale3d(xScale, yScale, 0);
BlockTableRecord cSpace = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
cSpace.AppendEntity(br);
tr.AddNewlyCreatedDBObject(br, true);
br.ExplodeToOwnerSpace();
br.Erase();
btr.Erase();
tr.Commit();
}
}