Dear Benjamin,
Thank you for your update.
One colleague suggested looking at the following method for retrieving an existing parameter definition, if it exists, or creating a new one, if not:
/// <summary>
/// Returns the ExternalDefinition to create a SharedParameter to add to a Revit document.
/// </summary>
/// <param name="doc">The document.</param>
/// <param name="name">The parameter name.</param>
/// <param name="groupName">The name of the group in the Shared Parmeter file.</param>
/// <param name="type">The type.</param>
/// <param name="visible">if set to <c>true</c> [visible].</param>
/// <param name="userModifiable">if set to <c>true</c> [user modifiable].</param>
/// <param name="cats">The cats.</param>
/// <param name="group">The group.</param>
/// <param name="inst">if set to <c>true</c> [inst].</param>
/// <returns></returns>
private ExternalDefinition RawCreateProjectParameter(Document doc, string name, string groupName, ParameterType type, bool visible, bool userModifiable, CategorySet cats, BuiltInParameterGroup group, bool inst)
{
Log(name);
ExternalDefinition def = null;
DefinitionGroup defGroup = null;
// (1) Check if the group exists in the Shared Parameters File
foreach (DefinitionGroup dg in doc.Application.OpenSharedParameterFile().Groups)
{
if (dg.Name == groupName)
{
Log(string.Format("DefinitionGroup {0} found.", groupName));
defGroup = dg;
break;
}
}
if (defGroup == null)
{
defGroup = doc.Application.OpenSharedParameterFile().Groups.Create(groupName);
Log(string.Format("DefinitionGroup {0} created.", groupName));
}
// (2) Check if the external definition exists in the Shared Parameters File
if (defGroup.Definitions.Cast<ExternalDefinition>().Where(x => x.Name == name).Count() > 0)
{
Log(string.Format("Exploring definitions...", ""));
foreach (ExternalDefinition ed in defGroup.Definitions.Cast<ExternalDefinition>())
{
bool t1 = ed.Name == name;
bool t2 = ed.ParameterType == type;
bool t3 = ed.Visible == visible;
bool t4 = ed.UserModifiable == userModifiable;
//bool t5 = ed.ParameterGroup == group;
if (t1 && t2 && t3 && t4)
{
def = ed;
Log(string.Format("ExternalDefinition {0} found.", name));
break;
}
}
}
if (def == null)
{
Log(string.Format("Creating definition...", ""));
ExternalDefinitionCreationOptions edco = new ExternalDefinitionCreationOptions(name, type);
edco.UserModifiable = userModifiable;
edco.Visible = visible;
def = defGroup.Definitions.Create(edco) as ExternalDefinition;
Log(string.Format("ExternalDefinition {0} created.", name));
}
if (def == null)
{
Log(string.Format("ExternalDefinition {0} is null.", name));
return null;
}
// (3) Check if the external definition has been already bound to the categories in the category set
CategorySet cs2 = new CategorySet();
try
{
BindingMap bm = doc.ParameterBindings;
foreach (Category cat in cats)
{
// Loop all Binding Definitions
// IMPORTANT NOTE: Categories.Size is ALWAYS 1 !?
// For multiple categories, there is really one
// pair per each category, even though the
// Definitions are the same...
DefinitionBindingMapIterator iter = doc.ParameterBindings.ForwardIterator();
bool found = true;
while (iter.MoveNext())
{
if (iter.Key.Name == name)
{
ElementBinding eb = (ElementBinding)iter.Current;
foreach (Category catEB in eb.Categories)
{
if (catEB.Id.IntegerValue.Equals(cat.Id.IntegerValue))
{
if (type == iter.Key.ParameterType)
{
if (group == iter.Key.ParameterGroup)
{
found = false;
break;
}
}
}
}
}
}
if (found)
{
cs2.Insert(cat);
}
}
if (cs2.Size == 0)
{
Log(string.Format("The Parameter already exists.", cs2.Size));
}
else
{
Log(string.Format("The Parameter will be bound to {0} categor{1}.", cs2.Size, cs2.Size == 1 ? "y" : "ies"));
Autodesk.Revit.DB.Binding binding = doc.Application.Create.NewTypeBinding(cs2);
if (inst)
{
binding = doc.Application.Create.NewInstanceBinding(cs2);
}
BindingMap map = doc.ParameterBindings;
map.Insert(def, binding, group);
Log(string.Format("Parameter bound successfully.", ""));
}
}
catch (Exception ex)
{
Log(string.Format("ERROR Creating Shared Parameter: {0}", ex.Message));
}
return def;
}
I have not yet heard back from the true IFC experts, though...
Here are my two cents on your last two questions:
> Is there some logical explanation for?
Yes.
> why Revit creates a new Revit model.ifc?
It creates a new model.ifc.rvt file in order to create appropriate placeholder elements needed for the linking process.
Best regards,
Jeremy