How to modify ifc file with xbim explorer

163 views Asked by At

When I add an element to an ifc file, I have always a newer ifcownerhistory, person and organization created. I open my file ifc file with .Net xbim xplorer like this, and I save the default ownerhistory for reuse it when I create a new element:

   private ObjectDataProvider ModelProvider
   {
       get
       {
           return MainFrame.DataContext as ObjectDataProvider;
       }
   }
   
   public IfcStore Model
   {
       get
       {
           var op = MainFrame.DataContext as ObjectDataProvider;
           return op == null ? null : op.ObjectInstance as IfcStore;
       }
   }
public bool LoadIFC()
{
    var model = IfcStore.Open(currentFileName);
    SetContext(model);
    if (Model != null)
    {
        owner = Model.Instances.OfType<IIfcOwnerHistory>().First();
        version = Model.SchemaVersion;
    }
}

private void SetContext(IfcStore model)
{
    var context = new Xbim3DModelContext(model);
    context.CreateContext();  
    ModelProvider.ObjectInstance = model;
    ModelProvider.Refresh();
}

Here is my code to add a task which work with ifcstore but not with memorymodel:

private void AddTask()
{
    if (_currentProduct == null) return;

        using (var txn = Model.BeginTransaction("Ajout IfcTask a un produit"))
        {
            try
            {
                
                IfcTask newIfcTask = Model.Instances.New<IfcTask>();
                newIfcTask.Name = "Test";
                newIfcTask.Description = "TaskDescription";
                newIfcTask.OwnerHistory = (IfcOwnerHistory)owner;
                
                IfcTaskTime taskTime = Model.Instances.New<IfcTaskTime>();
                taskTime.EarlyStart = new IfcDateTime(StartDate.ToString());
                taskTime.EarlyFinish = new IfcDateTime(EndDate.ToString());
                
                newIfcTask.TaskTime = taskTime;
                
            
                IfcRelAssignsToProduct relAssignsToProduct = Model.Instances.New<IfcRelAssignsToProduct>();
                relAssignsToProduct.RelatingProduct = _currentProduct;
                relAssignsToProduct.RelatedObjects.Add(newIfcTask);
               
                txn.Commit();
                
            }
            catch (Exception ex)
            {
                Debug.WriteLine("Erreur lors de la création de l'IfcTask : " + ex.Message);
                txn.RollBack();
            }
        }
}`

I want to reuse the default ownerhistory, thanks for help

1

There are 1 answers

14
Andy Ward On

If you're editing an IFC model with xbim you should always perform edits in a transaction, and commit the transaction before saving the model. Otherwise your edits will not be persisted.

So for example

            //Begin a transaction as all changes to a model are ACID
            using (var txn = model.BeginTransaction("Edit Model"))
            {

                //create a project
                var wall = model.Instances.New<IfcWall>();
                //and further set properties, relationships
                
                //now commit the changes, else they will be rolled back at the end of the scope of the using statement
                txn.Commit();
            }
            return model; 
            // then Save the model

If you're using IfcStore for your IModel implementation then all edits will automatically be linked with a new IfcOwnerHistory

If that's not what you want there are a couple of options:

  1. Use MemoryModel or EsentModel - neither of which add this convenience mechanism to assign edits to an OwnerHistory
  2. Subscribe to the IModel.EntityModified event handler, and post-fix the OwnerHistory
  3. Log an issue (and ideally a Pull Request) to make IfcStore.ManageOwnerHistory public and settable, so you can skip this behaviour.