cart: empty [ Login ]

DxfBlock not showing up in drawing...

1 
Earthbound
1/22/2008 4:54 PM
Hello, I am struggling to get a block inserted and showing up in a drawing. I have the veiwer control open and loaded with a drawing (dxf file). These files are all streamed from a database so my dxfTools class is functional. Here is s snipped of code: double x=0.0d, y=0.0d, z=1d; //create an instance of our dxf tools DXFTools dxfTools = new DXFTools(); //grab the current model in the viewer DxfModel model = this.Viewer.Model; //define and load the block data DxfModel blkmodel = new DxfModel(); blkmodel = DxfReader.ReadDxf(dxfTools.StreamFromDB(blkName)); DxfBlock blk = new DxfBlock(blkmodel, blkName); blk.Visible = true; //not sure this needs to be done.... //add it to the models block collection model.Blocks.Add(blk); //define a graphical entity point DxfInsert insblk = new DxfInsert(blk, new Point3D(x, y, z)); //load the block graphically model.Entities.Add(insblk); //this next line never shows the message, so clearly the block did not get added?.. if (model.Entities.Contains(blk)) MessageBox.Show('Block added'); //clean out the the old model this.Viewer.Clear(); //refresh the graphic control with the updated model containing the new block. this.Viewer.Model = model; What is it that I am doing wrong or misunderstanding about your framework? Thank you for your help.
Wout
1/24/2008 10:59 AM
Hi, This can be done, but slightly different than you attempted. It is a bit more complex than it seems at first when dealing with multiple DXF models. When you want to use a BLOCK from drawing A in drawing B, then all kinds of referenced objects like layers and line types must also be synchronized. E.g. a DxfCircle is on a DxfLayer, that layer object is related to a certain drawing, so you can't just add a circle instance from drawing A to drawing B, because they'd become entangled. In short, an object can only live in the context of one drawing, not more. When you want to use it in another drawing, you must use the Clone functionality of CadLib. See method DxfEntity.Clone(). So you can clone your source block in the context of your target drawing, and then you can add the clone to the target drawing and reference that from an INSERT. The Clone() method makes sure that referenced layers, line types, text styles are also cloned from the source to the target model in case they were missing. Wout
Earthbound
1/29/2008 6:11 PM
I follow this... (ref from your reply) 'So you can clone your source block in the context of your target drawing.' //grab the current model in the viewer DxfModel model = this.Viewer.Model; //define and load the block data DxfModel blkmodel = new DxfModel(); blkmodel = DxfReader.ReadDxf(dxfTools.StreamFromDB(blkName)); DxfBlock blk = new DxfBlock(blkmodel, blkName); blk.Visible = true; //clone the block into the model blk.Clone(model, ReferenceResolutionType.IgnoreMissing); Here is where you lost me: (ref from your reply) 'and then you can add the clone to the target drawing and reference that from an INSERT' Doesn't the clone method add the block entities to the target? What do I call to 'add' the blk and how do I acquire the reference to the INSERT?? Some sample code would really help clarify my questions. Thanks - Johan (Earthbound).
Wout
1/29/2008 6:38 PM
Hi Johan, From my understanding I'd write this:
C# Code:
DxfModel targetModel = this.Viewer.Model; DxfModel blockSourceModel = DxfReader.ReadDxf(dxfTools.StreamFromDB(blockName)); DxfBlock sourceBlock = blockSourceModel.Blocks[blockName]; DxfBlock clonedBlock = (DxfBlock)sourceBlock.Clone(targetModel, ReferenceResolutionType.CloneMissing); targetModel.Blocks.Add(clonedBlock); DxfInsert insert = new DxfInsert(clonedBlock); targetModel.Entities.Add(insert);
Let me know if this works for you! Wout
Earthbound
1/29/2008 7:21 PM
Wout, The code you provided works if the blockname exists as a block in the blockSourceModel, however, I am trying not 'extract' a block from the blockSourceModel and inserting into a targetModel drawing. My blockSourceModel is the block, that is getting inserted into the targetModel drawing. I have gone through some of the previous posts on your forum and have found a post by Clay and his attempt at doing what I am trying to do. I want to add all the entities of a drawing as a block into another drawing. He used the term 'merge' it is ineffect what I am trying to do. I have a template (target) dxf into which I want to add several other dxf files as blocks. If this is not possible I could take all my blocks and add them to a 'blockSource' dxf and extract them the way your code demonstrates. This is not optimal for our system as it would eventually cause a large memory footprint on the server once several users are working with the system simultaneously. I await your response and again thank you for your time - Johan.
Wout
1/29/2008 7:33 PM
Ah, gotcha. In that case you'd have to clone all Entities from the source model into the target model context, and add them to a new block. Something like this:
C# Code:
DxfBlock block = new DxfBlock(); foreach (DxfEntity sourceEntity in sourceModel.Entities) {   DxfEntity clonedEntity = (DxfEntity)sourceEntity.Clone(targetModel, ReferenceResolutionType.CloneMissing);   block.Entities.Add(clonedEntity); } targetModel.Blocks.Add(block); etc...
You'll have to determine what you want to clone exactly, it doesn't really matter what you want to clone, as long as you clone it properly. Wout
Earthbound
1/30/2008 2:03 AM
Wout, Thank you very much! I am comprehending your framework with much more clarity. This helps tremendously. I will get working on this tomorrow morning (PST). As soon as I get a prof-of-concept model working we will purchase your component. - Johan Earthbound Corp.
Earthbound
4/24/2008 2:24 AM
Hi Wout, I guess I do not have a handle on what you explained to me in this post. Please see the following code:
C# Code:
private void AddToTarget(DxfModel sourceModel, string blkName, Point3D Pnt3D) {   if( this._targetModel.Blocks.Contains(blkName) ) {//existing block     // block exists in target so just reinsert block into another position    this._targetModel.Entities.Add(new DxfInsert(this._targetModel.Blocks[blkName], Pnt3D));   } else { //add as a new block    //new empty instance of named block    DxfBlock blk = new DxfBlock(blkName);    int entCounter = 0;    //loop through and clone all the entities into our new block instance from the SourceModel    foreach (DxfEntity sourceEntity in sourceModel.Entities) {      DxfEntity clonedEntity = (DxfEntity)sourceEntity.Clone(      this._targetModel, ReferenceResolutionType.CloneMissing);      //add the cloned entity into the blk      blk.Entities.Add(clonedEntity);      entCounter++;    }    // Insert the block instance into position in our target model    this._targetModel.Entities.Add(new DxfInsert(blk, Pnt3D));   } }
if the block does not already exist in the _targetModel then I see the code above creating a new DxfBlock, cloning all the sourceModels entities into that DxfBlock then adding that DxfBlock via an DxfInsert into the _targetModel. However, what is really happening is that the DxfBlock is getting placed into the _targetModel entCount times. I fail to understand why this is happening. The last line in the code; this._targetModel.Entitiles.Add(new DxfInsert(blk, Pnt3D) is outside the loop! So how can that happen? I am very perplexed, please enlighten me! Thank you, Johan.
Wout
4/24/2008 6:14 PM
Hi Johan, One thing I see is missing: after creating the block, you must also add it to the DxfModel.Blocks. Other than that I don't see anything wrong. Wout
Earthbound
4/24/2008 8:24 PM
I feel rather rediculas now that I see that. I added the following line: //add the block definition to the target model this._targetModel.Blocks.Add(blk); prior to add the the DxfInser. Thank you once again. :-)
1