Setting Duct Width and Height Requires Regeneration
Originally Published inWhenever you have a problem modifying or querying the model with your Revit plug-in, one of the first things to check is always your regeneration mode. If you are using the manual regeneration option, you need to check whether you possibly omitted a required intermediate regeneration call. It seems that there can never be enough reminders of this. Here is another case at hand:
Question: I am sizing rectangular duct fittings through the API, and I noticed that the different dimensions for width and height must be set in different transactions. Otherwise, you lose the first size change when the second one is made.
Is this a feature or a bug?
The requirement to start and commit a separate transaction for each dimension change makes sizing of the network quite clumsy and even slow with larger drawings.
Here are two simple example code snippets in managed C++ setting the width and height of an elbow to 500x500 mm. They have both the TransactionMode and the RegenerationOption set to Manual. The first one uses a single transaction and does not work. The second uses two transactions and does.
Here is the first test with the size changes in same transaction:
Result AddinTest1::Execute(
ExternalCommandData^ commandData,
System::String^% message,
ElementSet^ elements)
{
Document ^doc = commandData->Application
->ActiveUIDocument->Document;
// Duct/bend IDs in example project
int west_east = 505594;
int north_south = 505598;
int bend_id = 505610;
ElementId ^elemId = gcnew ElementId(west_east);
Element ^ductElem1 = doc->Element::get(elemId);
elemId = gcnew ElementId(north_south);
Element ^ductElem2 = doc->Element::get(elemId);
elemId = gcnew ElementId(bend_id);
Element ^bendElem1 = doc->Element::get(elemId);
FamilyInstance ^bend
= safe_cast<FamilyInstance^>(bendElem1);
ConnectorSet ^cSet
= bend->MEPModel->ConnectorManager->Connectors;
Transaction tr(doc, L"sizing");
tr.Start();
for each (Connector ^connector in cSet)
{
if (connector->ConnectorType
!= ConnectorType::EndConn)
{
continue;
}
connector->Width::set((500 * 0.0032808399));
connector->Height::set((500 * 0.0032808399)); // This is not set into the drawing
break;
}
tr.Commit();
return Result::Succeeded;
}
```Here is the second test doing exactly the same thing but using two separate transactions:```csharp
Transaction tr(doc, L"sizing");
tr.Start();
// We do separate transactions for both dimensions
for each (Connector ^connector in cSet)
{
if (connector->ConnectorType
!= ConnectorType::EndConn)
{
continue;
}
connector->Width::set((500 * 0.0032808399));
break;
}
tr.Commit();
tr.Start();
for each (Connector ^connector in cSet)
{
if (connector->ConnectorType
!= ConnectorType::EndConn)
{
continue;
}
connector->Height::set((500 * 0.0032808399));
break;
}
tr.Commit();
Answer: I have two suggestions for you, but only one is meant seriously:
- You could use automatic regeneration mode. I would not recommend this, however, for many reasons, not least because it is obsolete and will soon be removed.
- You could try to regenerate the document between the setting of the two parameters. Does this help?
Response: Thanks for your quick and complete answer.
Yes, regeneration between those settings does help; no whole additional transaction procedure is needed.
Thanks again and best wishes for this New Year 2011!