Hey everyone,
I'm trying to create an array from one block with the option to specify columns, rows, respective offsets as well as angle. The original block comes from a 98kb dmg and is pre-inserted at a specific x,y,z in the model space. The issue I run into is whenever i try to create an array with say more than 200 lines and 200 columns, the machine locks up. It generally will create the array however it can take upwards of 5 minutes. What am i doing wrong?
Cheers
Vince
// Our list of Attributes BlockReference blockRef = bref; AttributeDefinition attDef1 = new AttributeDefinition(new Point3d(0d, 0d, 0d), type, "Type", "", db.Textstyle); attDef1.Invisible = true; AttributeDefinition attDef2 = new AttributeDefinition(new Point3d(0d, 0d, 0d), device, "Device", "", db.Textstyle); attDef2.Invisible = true; AttributeDefinition attDef3 = new AttributeDefinition(new Point3d(0d, 0d, 0d), kfactor, "Test", "", db.Textstyle); attDef3.Invisible = true; AttributeDefinition attDef4 = new AttributeDefinition(new Point3d(0d, 0d, 0d), size, "Size", "", db.Textstyle); attDef4.Invisible = true; AttributeDefinition attDef5 = new AttributeDefinition(new Point3d(0d, 0d, 0d), area1, "Area", "", db.Textstyle); attDef5.Invisible = true; AttributeDefinition attDef6 = new AttributeDefinition(new Point3d(0d, 0d, 0d), maxasp, "Test Area", "", db.Textstyle); attDef6.Invisible = true; AttributeDefinition attDef7 = new AttributeDefinition(new Point3d(0d, 0d, 0d), maxdsp, "Test Distance", "", db.Textstyle); attDef7.Invisible = true; AttributeDefinition attDef8 = new AttributeDefinition(new Point3d(0d, 0d, 0d), density, "Density", "", db.Textstyle); attDef8.Invisible = true; AttributeDefinition attDef9 = new AttributeDefinition(new Point3d(0d, 0d, 0d), weight, "Weight", "", db.Textstyle); attDef9.Invisible = true; AttributeDefinition attDef10 = new AttributeDefinition(new Point3d(0d, 0d, 0d), temp, "Temperature", "", db.Textstyle); attDef10.Invisible = true; AttributeDefinition attDef11 = new AttributeDefinition(new Point3d(0d, 0d, 0d), orfice, "Test", "", db.Textstyle); attDef11.Invisible = true; AttributeDefinition attDef12 = new AttributeDefinition(new Point3d(0d, 0d, 0d), price, "Price", "", db.Textstyle); attDef12.Invisible = true; AttributeDefinition attDef13 = new AttributeDefinition(new Point3d(0d, 0d, 0d), style, "Test", "", db.Textstyle); attDef13.Invisible = true; AttributeDefinition attDef14 = new AttributeDefinition(new Point3d(0d, 0d, 0d), finish, "Finish", "", db.Textstyle); attDef14.Invisible = true; AttributeDefinition attDef15 = new AttributeDefinition(new Point3d(0d, 0d, 0d), productinfo, "Web Link", "", db.Textstyle); attDef15.Invisible = true; // Add the attribute to to the BlockTableRecord of the blockdefinition of the selected block ObjectId btrId = blockRef.BlockTableRecord; BlockTableRecord btrBlock = (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForWrite); btrBlock.AppendEntity(attDef1); tr.AddNewlyCreatedDBObject(attDef1, true); btrBlock.AppendEntity(attDef2); tr.AddNewlyCreatedDBObject(attDef2, true); btrBlock.AppendEntity(attDef3); tr.AddNewlyCreatedDBObject(attDef3, true); btrBlock.AppendEntity(attDef4); tr.AddNewlyCreatedDBObject(attDef4, true); btrBlock.AppendEntity(attDef5); tr.AddNewlyCreatedDBObject(attDef5, true); btrBlock.AppendEntity(attDef6); tr.AddNewlyCreatedDBObject(attDef6, true); btrBlock.AppendEntity(attDef7); tr.AddNewlyCreatedDBObject(attDef7, true); btrBlock.AppendEntity(attDef8); tr.AddNewlyCreatedDBObject(attDef8, true); btrBlock.AppendEntity(attDef9); tr.AddNewlyCreatedDBObject(attDef9, true); btrBlock.AppendEntity(attDef10); tr.AddNewlyCreatedDBObject(attDef10, true); btrBlock.AppendEntity(attDef11); tr.AddNewlyCreatedDBObject(attDef11, true); btrBlock.AppendEntity(attDef12); tr.AddNewlyCreatedDBObject(attDef12, true); btrBlock.AppendEntity(attDef13); tr.AddNewlyCreatedDBObject(attDef13, true); btrBlock.AppendEntity(attDef14); tr.AddNewlyCreatedDBObject(attDef14, true); btrBlock.AppendEntity(attDef15); tr.AddNewlyCreatedDBObject(attDef15, true); // Add the AttributeReference to the BlockReference AttributeReference attRef1 = new AttributeReference(); attRef1.SetAttributeFromBlock(attDef1, blockRef.BlockTransform); blockRef.AttributeCollection.AppendAttribute(attRef1); attRef1.AdjustAlignment(db); tr.AddNewlyCreatedDBObject(attRef1, true); AttributeReference attRef2 = new AttributeReference(); attRef2.SetAttributeFromBlock(attDef2, blockRef.BlockTransform); blockRef.AttributeCollection.AppendAttribute(attRef2); attRef2.AdjustAlignment(db); tr.AddNewlyCreatedDBObject(attRef2, true); AttributeReference attRef3 = new AttributeReference(); attRef3.SetAttributeFromBlock(attDef3, blockRef.BlockTransform); blockRef.AttributeCollection.AppendAttribute(attRef3); attRef3.AdjustAlignment(db); tr.AddNewlyCreatedDBObject(attRef3, true); AttributeReference attRef4 = new AttributeReference(); attRef4.SetAttributeFromBlock(attDef4, blockRef.BlockTransform); blockRef.AttributeCollection.AppendAttribute(attRef4); attRef4.AdjustAlignment(db); tr.AddNewlyCreatedDBObject(attRef4, true); AttributeReference attRef5 = new AttributeReference(); attRef5.SetAttributeFromBlock(attDef5, blockRef.BlockTransform); blockRef.AttributeCollection.AppendAttribute(attRef5); attRef5.AdjustAlignment(db); tr.AddNewlyCreatedDBObject(attRef5, true); AttributeReference attRef6 = new AttributeReference(); attRef6.SetAttributeFromBlock(attDef6, blockRef.BlockTransform); blockRef.AttributeCollection.AppendAttribute(attRef6); attRef6.AdjustAlignment(db); tr.AddNewlyCreatedDBObject(attRef6, true); AttributeReference attRef7 = new AttributeReference(); attRef7.SetAttributeFromBlock(attDef7, blockRef.BlockTransform); blockRef.AttributeCollection.AppendAttribute(attRef7); attRef7.AdjustAlignment(db); tr.AddNewlyCreatedDBObject(attRef7, true); AttributeReference attRef8 = new AttributeReference(); attRef8.SetAttributeFromBlock(attDef8, blockRef.BlockTransform); blockRef.AttributeCollection.AppendAttribute(attRef8); attRef8.AdjustAlignment(db); tr.AddNewlyCreatedDBObject(attRef8, true); AttributeReference attRef9 = new AttributeReference(); attRef9.SetAttributeFromBlock(attDef9, blockRef.BlockTransform); blockRef.AttributeCollection.AppendAttribute(attRef9); attRef9.AdjustAlignment(db); tr.AddNewlyCreatedDBObject(attRef9, true); AttributeReference attRef10 = new AttributeReference(); attRef10.SetAttributeFromBlock(attDef10, blockRef.BlockTransform); blockRef.AttributeCollection.AppendAttribute(attRef10); attRef10.AdjustAlignment(db); tr.AddNewlyCreatedDBObject(attRef10, true); AttributeReference attRef11 = new AttributeReference(); attRef11.SetAttributeFromBlock(attDef11, blockRef.BlockTransform); blockRef.AttributeCollection.AppendAttribute(attRef11); attRef11.AdjustAlignment(db); tr.AddNewlyCreatedDBObject(attRef11, true); AttributeReference attRef12 = new AttributeReference(); attRef12.SetAttributeFromBlock(attDef12, blockRef.BlockTransform); blockRef.AttributeCollection.AppendAttribute(attRef12); attRef12.AdjustAlignment(db); tr.AddNewlyCreatedDBObject(attRef12, true); AttributeReference attRef13 = new AttributeReference(); attRef13.SetAttributeFromBlock(attDef13, blockRef.BlockTransform); blockRef.AttributeCollection.AppendAttribute(attRef13); attRef13.AdjustAlignment(db); tr.AddNewlyCreatedDBObject(attRef13, true); AttributeReference attRef14 = new AttributeReference(); attRef14.SetAttributeFromBlock(attDef14, blockRef.BlockTransform); blockRef.AttributeCollection.AppendAttribute(attRef14); attRef14.AdjustAlignment(db); tr.AddNewlyCreatedDBObject(attRef14, true); AttributeReference attRef15 = new AttributeReference(); attRef15.SetAttributeFromBlock(attDef15, blockRef.BlockTransform); blockRef.AttributeCollection.AppendAttribute(attRef15); attRef15.AdjustAlignment(db); tr.AddNewlyCreatedDBObject(attRef15, true); // These two are disabled as they generate an old block reference made up of circles and lines //bref.ExplodeToOwnerSpace(); // bref.Erase(); //Create a rectangular array with 5 rows and 5 columns double nRows = prilines; double nColumns = seclines; //Set the row and column offsets along with the base array angle double dRowOffset = msprinkdist; double dColumnOffset = mlinedist; double dArrayAng = 0; //Get the angle from x for the current UCS Matrix3d curUCSMatrix = acDoc.Editor.CurrentUserCoordinateSystem; CoordinateSystem3d curUCS = curUCSMatrix.CoordinateSystem3d; Vector2d acVec2dAng = new Vector2d(curUCS.Xaxis.X, curUCS.Xaxis.Y); //If the UCS is rotated, adjust the array angle accordingly dArrayAng = dArrayAng + acVec2dAng.Angle; //Use the upper-left corner of the objects extents for the array base point Extents3d acExts = bref.Bounds.GetValueOrDefault(); Point2d acPt2dArrayBase = new Point2d(acExts.MinPoint.X, acExts.MaxPoint.Y); //Track the objects created for each column DBObjectCollection acDBObjCollCols = new DBObjectCollection(); acDBObjCollCols.Add(bref); //Create the number of objects in the first column int nColumnsCount = 1; while (nColumns > nColumnsCount) { BlockReference acEntClone = bref.Clone() as BlockReference; acDBObjCollCols.Add(acEntClone); //Calculate the new point for the copied object (move) Point2d acPt2dTo = PolarPoints(acPt2dArrayBase, dArrayAng, dColumnOffset * nColumnsCount); Vector2d acVec2d = acPt2dArrayBase.GetVectorTo(acPt2dTo); Vector3d acVec3d = new Vector3d(acVec2d.X, acVec2d.Y, 0); acEntClone.TransformBy(Matrix3d.Displacement(acVec3d)); btr.AppendEntity(acEntClone); acTrans.AddNewlyCreatedDBObject(acEntClone, true); acEntClone.ExplodeToOwnerSpace(); nColumnsCount = nColumnsCount + 1; } //Set a value in radians for 90 degress double dAng = Math.PI / 2; //Track the objects created for each row and column DBObjectCollection acDBObjCollLvls = new DBObjectCollection(); foreach (DBObject acObj in acDBObjCollCols) { acDBObjCollLvls.Add(acObj); } // Create the number of objects for each row foreach (Entity acEnt in acDBObjCollCols) { int nRowsCount = 1; while (nRows > nRowsCount) { BlockReference acEntClone = acEnt.Clone() as BlockReference; acDBObjCollLvls.Add(acEntClone); //Calculate the new point for the copied object (move) Point2d acPt2dTo = PolarPoints(acPt2dArrayBase, dArrayAng + dAng, dRowOffset * nRowsCount); Vector2d acVec2d = acPt2dArrayBase.GetVectorTo(acPt2dTo); Vector3d acVec3d = new Vector3d(acVec2d.X, acVec2d.Y, 0); acEntClone.TransformBy(Matrix3d.Displacement(acVec3d)); btr.AppendEntity(acEntClone); acTrans.AddNewlyCreatedDBObject(acEntClone, true); nRowsCount = nRowsCount + 1; } } tr.Commit(); ed.Regen(); } } } } }
I know it has been a long time since you posted this, but I was just poking around my profile, and noticed a saved draft response, that I apparently never sent, and no one else seems to have replied either; so hopefully you have figured some of this out on your own, but for the benefit of others, and in case you haven't, here is what was in my saved draft from 8 months ago.
Well, consider the fact that with a 200 x 200 array, at the end of this function you will have 40,000 block references OPEN in memory, plus the Block Table Record, the Attribute Definitions, and the first set of Attribute References.
After you have appended the AttributeReferences to the block, you don't refer to them any more, so they can be disposed, as well as the AttributeDefinitions. Then, at least as the code is posted here, you are not doing anything with the BlockReferences after they are created, but you are putting them in a DbObjectCollection, which keeps them open until the commit. You should dispose each one immediately after adding it to the database and transaction.
If you are intending on performing some other operation on them after adding, you should do it inside the loop where it gets created, and dispose them after that.
I might even go so far as to say, it would be better to end the first transaction after adding the attributes, before starting the clone loops, and start a new transaction for every clone loop. That's a lot of transactions, I know, but it would help keep the memory from filling up.
Hello,
Thanks for the response. As a matter of fact, looking back on my code, I believe i did just that after a while of researching and experimenting!
Thanks
Glad you figured it out, sorry I didn't help you figure it out quicker.
I must have been really busy that day, and got sidetracked.
In fact, thinking back on it now, I vaguely recall doing a test of sorts, creating my own large array. I think I was trying to verify my advice before posting it, but then never got around to finishing the deed.