Message 1 of 7
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Hi Everybody.
I want to align two families by their connectors. Graphically it is shown in picture below. Families can be placed in any direction in 3D space. Any axis of any element is not to parallel to each other and project coordinates.
My code is at below. I explained code as much as I could. The code is working when element located parallel to project axes. But it doesn't in other situations.
Am I in the wrong path? Is there a better way to do it?
private: static void rotate(UIApplication^ uiapp, elmstoreplace^ elms)
{
// Select some elements in Revit before invoking this command
// Get the handle of current document.
UIDocument^ uidoc = uiapp->ActiveUIDocument;
Document^ doc = uidoc->Document;
// Elelements are stored in other header. We will read from there.
// We saved them there by selecting in GUI.
Element^ elmfrom = doc->GetElement(elmstoreplace::elmFrom); // Element will be aligned.
Element^ elmto = doc->GetElement(elmstoreplace::elmTo); // Element will be aligned to.
// 1. Cast Element to FamilyInstance
FamilyInstance^ faminstfrom = (FamilyInstance^)elmfrom;
FamilyInstance^ faminstto = (FamilyInstance^)elmto;
// 2. Get MEPModel Property
MEPModel^ mepmodelfrom = faminstfrom->MEPModel;
MEPModel^ mepmodelto = faminstto->MEPModel;
// 3. Get connector set of MEPModel
ConnectorSet^ connectorSetfrom = mepmodelfrom->ConnectorManager->Connectors;
ConnectorSet^ connectorSetto = mepmodelto->ConnectorManager->Connectors;
// Connector numbers to be aligned to each other are stored in other file.
// We saved them there by selecting in GUI.
Connector^ connFrom =nullptr; // Connector will be aligned.
Connector^ connTo = nullptr; // Connector to be aligned to.
// Get connector by iterating in connectorset.
for each (Connector ^ connector in connectorSetfrom)
{
if (connector->Id == elmstoreplace::connNoFrom)
{
connFrom = connector;
}
}
// Get connector by iterating in connectorset.
for each (Connector ^ connector in connectorSetto)
{
if (connector->Id == elmstoreplace::connNoTo)
{
connTo = connector;
}
}
// Get the element current location
LocationPoint^ elmfromLoc = (LocationPoint^)elmfrom->Location;
// Create vector based on element location and connector location.
XYZ^ diffvec1 = connFrom->Origin->Subtract(elmfromLoc->Point);
// Subtract element location which will be moved.
XYZ^ diffvec2 = connTo->Origin->Subtract(elmfromLoc->Point);
// Bring two connectors to same point
ElementTransformUtils::MoveElement(doc, elmfrom->Id, diffvec2->Add(diffvec1->Negate()));
// Get basisZ of connectors.
XYZ^ basisZTo = connTo->CoordinateSystem->BasisZ;
// Transform vector.
XYZ^ getOfbasisZTo = getOfVector(basisZTo);
// Get basisZ of connectors.
XYZ^ basisZFrom = connFrom->CoordinateSystem->BasisZ;
// Transform vector.
XYZ^ getOfbasisZFrom = getOfVector(basisZFrom);
// Calculate angle between connectors.
double angle = getOfbasisZTo->AngleTo(getOfbasisZFrom);
// Calculate crossproduct of two vectors.
XYZ^ crossprod = getOfbasisZTo->CrossProduct(getOfbasisZFrom);
// Calculate crossproduct of two vectors.
// Somehow this always give unit vectors
// BasisX(1,0,0), BasisY(0,1,0), BasisX(0,0,1)
// I think that is my problem.
XYZ^ getOfcrossprod = getOfVector(crossprod);
// Create rotation axis.
Line^ rotationaxis = Line::CreateUnbound(connTo->Origin, crossprod->BasisZ);
// Rotate element around axis.
ElementTransformUtils::RotateElement(doc, elmfrom->Id, rotationaxis, Math::PI - angle);
}
public: static XYZ^ getOfVector(XYZ^ xyz)
{
XYZ^ OfVector(xyz);
return xyz;
}
Solved! Go to Solution.
Developer Advocacy and Support +