New Family Type with New Values on its Parameters

New Family Type with New Values on its Parameters

escarillabj
Explorer Explorer
333 Views
4 Replies
Message 1 of 5

New Family Type with New Values on its Parameters

escarillabj
Explorer
Explorer

Hi! I'm BJ.
So I recently started learning Revit API and C#. I took some short course.
In order for me to practice what i learn, I thought of creating my own mini project.

My goal is to create a tool/plugin where I can create a new family type with same parameters (height, width, diameter, material, visibility, and description) but different value. (example. Height= 450mm then new family has 500mm). This will later on have a window form as its user interface.

But for now, i am focusing on building the correct code to start.
So I started with coding the selection of the element in the Revit file
then read the element ID
get its parameter value
and replace to a new one
but it seems like when i select the element placed. It doesn't read the intended parameter.
Is it possible to have personalize parameters to be adjusted?

Also, if i need to rework on the entire code, any suggestions, recommendations or comments are very much welcome and is a big big help. (The current code is like an initial code from www.revitapidocs.com and I tweaked it a little bit)

I have placed the code below and attached the sample test file for your reference.

Cheers,
BJ


namespace BJPracticePluginTools
{
[TransactionAttribute(TransactionMode.Manual)]
public class CreateNewType : IExternalCommand
{
public void EditFamilyTypes(Document document, FamilyInstance familyInstance)
{
// example works best when familyInstance is a rectangular concrete element

if ((null == document) || (null == familyInstance.Symbol))
{
return; // invalid arguments
}

// Get family associated with this
Family family = familyInstance.Symbol.Family;
if (null == family)
{
return; // could not get the family
}

// Get Family document for family
Document familyDoc = document.EditFamily(family);
if (null == familyDoc)
{
return; // could not open a family for edit
}

FamilyManager familyManager = familyDoc.FamilyManager;
if (null == familyManager)
{
return; // cuould not get a family manager
}

// Start transaction for the family document
using (Transaction newFamilyTypeTransaction = new Transaction(familyDoc, "Add Type to Family"))
{
int changesMade = 0;
newFamilyTypeTransaction.Start();

// add a new type and edit its parameters
FamilyType newFamilyType = familyManager.NewType("2X2");

if (newFamilyType != null)
{
// look for 'b' and 'h' parameters and set them to 2 feet
FamilyParameter familyParam = familyManager.get_Parameter("Height");
if (null != familyParam)
{
familyManager.Set(familyParam, 2000.0);
changesMade += 1;
}

familyParam = familyManager.get_Parameter("Width");
if (null != familyParam)
{
familyManager.Set(familyParam, 2000.0);
changesMade += 1;
}
}

if (2 == changesMade) // set both paramaters?
{
newFamilyTypeTransaction.Commit();
}
else // could not make the change -> should roll back
{
newFamilyTypeTransaction.RollBack();
}

// if could not make the change or could not commit it, we return
if (newFamilyTypeTransaction.GetStatus() != TransactionStatus.Committed)
{
return;
}
}

// now update the Revit project with Family which has a new type
LoadOpts loadOptions = new LoadOpts();

// This overload is necessary for reloading an edited family
// back into the source document from which it was extracted
family = familyDoc.LoadFamily(document, loadOptions);
if (null != family)
{
// find the new type and assign it to FamilyInstance
ISet<ElementId> familySymbolIds = family.GetFamilySymbolIds();
foreach (ElementId id in familySymbolIds)
{
FamilySymbol familySymbol = family.Document.GetElement(id) as FamilySymbol;
if ((null != familySymbol) && familySymbol.Name == "2X2")
{
using (Transaction changeSymbol = new Transaction(document, "Change Symbol Assignment"))
{
changeSymbol.Start();
familyInstance.Symbol = familySymbol;
changeSymbol.Commit();
}
break;
}
}
}
}

public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
throw new NotImplementedException();
}

class LoadOpts : IFamilyLoadOptions
{
public bool OnFamilyFound(bool familyInUse, out bool overwriteParameterValues)
{
overwriteParameterValues = true;
return true;
}

public bool OnSharedFamilyFound(Family sharedFamily, bool familyInUse, out FamilySource source, out bool overwriteParameterValues)
{
source = FamilySource.Family;
overwriteParameterValues = true;
return true;
}
}
}
}



0 Likes
334 Views
4 Replies
Replies (4)
Message 2 of 5

Mohamed_Arshad
Advisor
Advisor

HI @escarillabj 


  Hats off to your efforts first. I look into you code completely it was perfectly alright. I found a issue in your code and one suggestion. Kindly check the below points

 

1. You're trying to load back the edited family in your Family Document not in Project Document.

 

Mohamed_Arshad_0-1694789987288.png

 

Just Change familyDoc To document
            // This overload is necessary for reloading an edited family
            // back into the source document from which it was extracted
            family = document.LoadFamily(document, loadOptions);

 

The Suggestion was kindly use OOPS concept to increase your code readability. And I didn't understand that what you mentioning about intended parameter. Family not loading or family parameter not visible. I didn't get this point can you please explain it briefly?

 

 

 

 

 


Mohamed Arshad K
Software Developer (CAD & BIM)

0 Likes
Message 3 of 5

escarillabj
Explorer
Explorer

a

0 Likes
Message 4 of 5

escarillabj
Explorer
Explorer

Hi, Mohamed!

Thank you for the input. I appreciate it. Apparently, when I tried changing the famDoc to document, it got thrown out. Not sure why.

As for the parameter, here's a little mind map i made to give a clearer picture of my goal.

escarillabj_0-1694996639975.png

 


But, right now, my first step is to try to find a way and learn how to write correctly the code  where I can change the the height and width parameter. then test run the plugin. then move on to the other parameters. Once I can master this step, I then plan to learn how to create the windows form.

At the moment, im stuck with the Height and Width parameter thing.

By the way, thanks for the suggestion. Im currently checking some online videos explaining the OOPS concept. Im not yet familiar with those.

Cheers,
BJ Escarilla

0 Likes
Message 5 of 5

Mohamed_Arshad
Advisor
Advisor

HI @escarillabj 


   I debug you code and found the reason of  your error while loading, When you change the parameter value you have to give value in feet for example your window size was 2000 mm means you have give 6.561679790026247 ft then in model it become 2000 mm. Kindly check the below code for reference.

 

 

 if (newFamilyType != null)
                {
                    // look for 'b' and 'h' parameters and set them to 2 feet
                    FamilyParameter familyParam = familyManager.get_Parameter("Height");
                    if (null != familyParam)
                    {
                        familyManager.Set(familyParam, 2000.0/304.8); //Here my project unit was mm and I need 2000mm
                        //converting mm to feet
                        changesMade += 1;
                    }

                    familyParam = familyManager.get_Parameter("Width");
                    if (null != familyParam)
                    {
                        familyManager.Set(familyParam, 2000.0/304.8);
                        changesMade += 1;
                    }
                }

 

After changing this your code works fine, Kindly Change and run you code. And Kindly follow the below Steps for your Next Plan

 

1. Get FamilySymbol using FilteredElementCollector
2. Duplicate with New Name
3. Edit Parameters using FamilySymbol.LookupParameters("Height");
4. Set New Value
5. Change the FamilySymbol of the created instance.

 

Hope this will helps 🙂

 


Mohamed Arshad K
Software Developer (CAD & BIM)

0 Likes