Hi,
I'm trying to associate the material parameter on an extrusion with a family parameter.
Open a new structural column family (I used the out of the box Metric Structural Column.rft) and run the attached code.
A document regeneration exception is thrown. I can manually associate the parameter after.
Any advice appreciated.
Cheers,
Jon
Solved! Go to Solution.
Solved by Aaron.Lu. Go to Solution.
I assume this is a bug in Revit???
If I haven't explained clearly, please let me know and I will clarify.
Thanks,
Jon
This is working now in Revit 2016:
private static bool SetFamilyMaterial(Document famdoc, Sweep geo, ElementId mId)
{
if (geo.get_Parameter(BuiltInParameter.MATERIAL_ID_PARAM) != null)
{
Parameter param = geo.get_Parameter(BuiltInParameter.MATERIAL_ID_PARAM);
if (param.Set(mId))
{
FamilyParameter famparam = famdoc.FamilyManager.get_Parameter(BuiltInParameter.STRUCTURAL_MATERIAL_PARAM);
if (famparam != null && famdoc.FamilyManager.CanElementParameterBeAssociated(param))
{
try
{
famdoc.FamilyManager.Set(famparam, param.AsElementId());
famdoc.FamilyManager.AssociateElementParameterToFamilyParameter(param, famparam);
return true;
}
catch (Exception ex1)
{
MessageBox.Show(ex1.ToString());
return false;
}
}
else
{
return false;
}
}
else
{
return false;
}
}
else
{
return false;
}
}
Hello chhadi,
your solution looks interesting. I just want to be able to change my Material type either within a Family document upon creation, or once the FamilyInstance is available, whichever is possible. Sounds trivial, but seems to be an epic in Revit.
In your method, what is "ElementId mId"?
dirk
Hi Dirk,
I am creating the material on the outside and just passing the id into this function. The material live in the document and I have a script that creates all our needed families.
regards
Christian
PS: Everything in Revit is an epic approach. 😉
Hello CHristian,
thanks for your quick Response. One more question:
I am adding a FamilyParameter for "Material" to the Family I generate, using the following code:
FamilyParameter familyParameter
= familyMgr.AddParameter("Material", BuiltInParameterGroup.PG_MATERIALS, ParameterType.Material, true);
When I run your Method using the ElementId of the Material, I get
famparam == null
at the following Point:
FamilyParameter famparam = famdoc.FamilyManager.get_Parameter(BuiltInParameter.STRUCTURAL_MATERIAL_PARAM);
So the "Material" FamilyParameter I added before is not recognised. How can I get it to be recognised?
Greetings, DIrk
Hi Dirk,
I dont understand. Why do you need to make a new material parameter. This thing should already be there. Do you have Revit lookup installed? Helps a lot in finding out what parameters are in the document or on the element.
I never create a new material parameter, but do create a new material and assign it to the existing parameter.
public static List<ElementId> Set(Document doc, Document famdoc, FamilyEntry f) { List<ElementId> mIds = new List<ElementId>(); Material m1 = Materials.GetMaterials(doc, f.Material1.Name); ElementId mId1, mId2; if (m1 != null) { using (Transaction trans = new Transaction(famdoc, "Change Material Color")) { try { trans.Start(); mId1 = Material.Create(famdoc, f.Material1.Name); if (mId1 != null) { Material mat1 = famdoc.GetElement(mId1) as Material; AppearanceAssetElement asset1 = doc.GetElement(m1.AppearanceAssetId) as AppearanceAssetElement; AppearanceAssetElement asset2 = AppearanceAssetElement.Create(famdoc, f.Material1.Name, asset1.GetRenderingAsset()); FilteredElementCollector coll = new FilteredElementCollector(famdoc).OfClass(typeof(FillPatternElement)); FillPatternElement pattern = null; if (f.Material1.Name == "your material name1") { pattern = coll.FirstOrDefault<Element>(e => e.Name.Equals("Steel")) as FillPatternElement; } else if (f.Material1.Name == "your material name2") { pattern = coll.FirstOrDefault<Element>(e => e.Name.Equals("Solid fill")) as FillPatternElement; } mat1.UseRenderAppearanceForShading = m1.UseRenderAppearanceForShading; mat1.StructuralAssetId = asset2.Id; mat1.Color = m1.Color; if (pattern != null) { mat1.CutPatternId = pattern.Id; } mat1.CutPatternColor = m1.CutPatternColor; mat1.AppearanceAssetId = m1.AppearanceAssetId; mat1.SurfacePatternId = m1.SurfacePatternId; mat1.SurfacePatternColor = m1.SurfacePatternColor; FamilyParameter fam_param1 = famdoc.FamilyManager.get_Parameter(BuiltInParameter.STRUCTURAL_MATERIAL_PARAM); if (fam_param1 != null) { famdoc.FamilyManager.Set(fam_param1, mId1); } Parameter doc_param = m1.get_Parameter(BuiltInParameter.FILL_PATTERN_ID_PARAM); FamilyParameter fam_param2 = famdoc.FamilyManager.get_Parameter(BuiltInParameter.FILL_PATTERN_ID_PARAM); if (doc_param != null && fam_param2 != null) { famdoc.FamilyManager.Set(fam_param2, doc_param.AsElementId()); } if (f.Material2 != null) { Material m2 = Materials.GetMaterials(doc, f.Material2.Name); mId2 = Material.Create(famdoc, f.Material2.Name); if (mId2 != null) { if (f.Material1.Name == "your material name1") { pattern = coll.FirstOrDefault<Element>(e => e.Name.Equals("Steel")) as FillPatternElement; } else if (f.Material1.Name == "your material name2") { pattern = coll.FirstOrDefault<Element>(e => e.Name.Equals("Solid fill")) as FillPatternElement; } Material mat2 = famdoc.GetElement(mId2) as Material; mat2.UseRenderAppearanceForShading = m2.UseRenderAppearanceForShading; mat2.StructuralAssetId = m2.StructuralAssetId; mat2.Color = m2.Color; if (pattern != null) { mat2.CutPatternId = pattern.Id; } mat2.CutPatternColor = m2.CutPatternColor; mat2.SurfacePatternColor = m2.SurfacePatternColor; FamilyParameter fam_param = famdoc.FamilyManager.AddParameter("Concrete Material", BuiltInParameterGroup.PG_MATERIALS, ParameterType.Material, false); if (fam_param != null) { famdoc.FamilyManager.Set(fam_param, mId2); } } } else { mId2 = null; } if (trans.Commit() == TransactionStatus.Committed) { mIds.Add(mId1); if (mId2 != null) { mIds.Add(mId2); } return mIds; } } } catch (Exception e) { MessageBox.Show(e.ToString()); } } } return null; }
This is the current code that I am using to assign the materials to the family extrusions. Hope it helps. FamilyEntry is just a generic datatype that holds all the stuff I need.
regards
Christian
Hello Christian,
yes I figured that out now as well. I just have to do this:
prm = solid.get_Parameter(BuiltInParameter.MATERIAL_ID_PARAM);
isSet = prm.Set(rubber.Id);
Thanks for your code. What are the following?
FamilyEntry f
Materials: Materials Collection?
No I don't have Revit lookup installed.
I would like to assign and use additional Parameters for things like Dates, and Production values and Input from surveying. How can I Access the FamilyParameters which I created when I am in FamilyInstance?
dirk
FamilyEntry is just my own datatype and the material collection is a list of all available materials in the document.
When you create a new FamilyParameter you have it right at this time. If you want to access is later you will need to close the transaction so the parameter gets written to the document/element.
regards
Christian
PS: Get Revit Lookup. Helps a lot.
Ok thanks for the info, and I'll get
I define a FamilyParameter as follows:
familyParameter = familyMgr.AddParameter("HT_ROTATION_TUNNEL", BuiltInParameterGroup.PG_GEOMETRY, ParameterType.Length, true);
When I look for it in the FamilyInstance fi, I cannot find it:
IList<Parameter> parms = fi.GetOrderedParameters();
foreach (Parameter parm in parms)
{
if ((parm.Definition.Name == "HT_ROTATION_TUNNEL"))
{
s = string.Format("{0}.{1}", parm.Definition.Name, Globalcounter);
}
}
What is the relationship between FamilyParameter and ordinary builtin-type?
Builtin comes with the template you are using. Custom stuff you need to define.
regards
christian
Ok thanks, one last question:
In your method SetFamilyMaterial, you use bothe built-in and FamilyParameters.
When I use the method it breaks here, because famparam returns null :
Parameter param = geo.get_Parameter(BuiltInParameter.MATERIAL_ID_PARAM);
if (param.Set(mId))
{
FamilyParameter famparam = fm.get_Parameter(BuiltInParameter.STRUCTURAL_MATERIAL_PARAM);
->if (famparam != null && fm.CanElementParameterBeAssociated(param))
Why can't I find
famparam = fm.get_Parameter(BuiltInParameter.STRUCTURAL_MATERIAL_PARAM);
in my Family?
I really appreciate your help!
What type of family template are you using? A structural template like column or framing?
Christian
No, I am using templateName = @"M_Mechanische Geräte.rft";
The english Version is "Metric Mechanical Equipment.rft"
It was the only template which allowed me to rotate and translate the FamilyInstance in 6 degrees of freedom (x,y,z, rot_x,rot_y,rot_z). But it has other drawbacks, such as not containing any usefule Materials.
Can't find what you're looking for? Ask the community or share your knowledge.