public InstanceObject BlockInstanceToNative(BlockInstance instance) { // get the block definition InstanceDefinition definition = BlockDefinitionToNative(instance.blockDefinition); // get the transform if (instance.transform.Length != 16) { return(null); } Transform transform = new Transform(); int count = 0; for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if (j == 3 && i != 3) // scale the delta values for translation transformations { transform[i, j] = ScaleToNative(instance.transform[count], instance.units); } else { transform[i, j] = instance.transform[count]; } count++; } } // create the instance if (definition == null) { return(null); } Guid instanceId = Doc.Objects.AddInstanceObject(definition.Index, transform); if (instanceId == Guid.Empty) { return(null); } return(Doc.Objects.FindId(instanceId) as InstanceObject); }
// Rhino convention seems to order the origin of the vector space last instead of first // This results in a transposed transformation matrix - may need to be addressed later public BlockInstance BlockInstanceToSpeckle(RH.InstanceObject instance) { var t = instance.InstanceXform; var transformArray = new double[] { t.M00, t.M01, t.M02, t.M03, t.M10, t.M11, t.M12, t.M13, t.M20, t.M21, t.M22, t.M23, t.M30, t.M31, t.M32, t.M33 }; var def = BlockDefinitionToSpeckle(instance.InstanceDefinition); var _instance = new BlockInstance() { insertionPoint = PointToSpeckle(instance.InsertionPoint), transform = transformArray, blockDefinition = def, units = ModelUnits }; return(_instance); }
public Group BlockInstanceToNative(BlockInstance instance, Transform transform = null) { // need to combine the two transforms, but i'm stupid and did it wrong so leaving like this for now if (transform != null) { transform *= instance.transform; } else { transform = instance.transform; } // convert definition geometry to native var breps = new List <Brep>(); var meshes = new List <Mesh>(); var curves = new List <DB.Curve>(); var blocks = new List <BlockInstance>(); foreach (var geometry in instance.blockDefinition.geometry) { switch (geometry) { case Brep brep: var success = brep.TransformTo(transform, out var tbrep); if (success) { breps.Add(tbrep); } else { Report.LogConversionError(new SpeckleException( $"Could not convert block {instance.id} brep to native, falling back to mesh representation.")); meshes.Add(tbrep.displayMesh); } break; case Mesh mesh: mesh.TransformTo(transform, out var tmesh); meshes.Add(tmesh); break; case ICurve curve: try { if (curve is ITransformable tCurve) { tCurve.TransformTo(transform, out tCurve); curve = ( ICurve )tCurve; } var modelCurves = CurveToNative(curve); curves.AddRange(modelCurves.Cast <DB.Curve>()); } catch (Exception e) { Report.LogConversionError( new SpeckleException($"Could not convert block {instance.id} curve to native.", e)); } break; case BlockInstance blk: blocks.Add(blk); break; } } var ids = new List <ElementId>(); breps.ForEach(o => { ids.Add((DirectShapeToNative(o).NativeObject as DB.DirectShape)?.Id); }); meshes.ForEach(o => { ids.Add((DirectShapeToNative(o).NativeObject as DB.DirectShape)?.Id); }); curves.ForEach(o => { ids.Add(Doc.Create.NewModelCurve(o, NewSketchPlaneFromCurve(o, Doc)).Id); }); blocks.ForEach(o => { ids.Add(BlockInstanceToNative(o, transform).Id); }); var group = Doc.Create.NewGroup(ids); group.GroupType.Name = $"SpeckleBlock_{instance.blockDefinition.name}_{instance.applicationId ?? instance.id}"; return(group); }
// Creates a generic model instance in a project or family doc public string BlockInstanceToNative(BlockInstance instance, Document familyDoc = null) { string result = null; // Base point var basePoint = PointToNative(instance.insertionPoint); // Get or make family from block definition FamilySymbol familySymbol = new FilteredElementCollector(Doc) .OfClass(typeof(Family)) .OfType <Family>() .FirstOrDefault(f => f.Name.Equals("SpeckleBlock_" + instance.blockDefinition.name)) ?.GetFamilySymbolIds() .Select(id => Doc.GetElement(id)) .OfType <FamilySymbol>() .First(); if (familySymbol == null) { var familyPath = BlockDefinitionToNative(instance.blockDefinition); if (familyDoc != null) { if (familyDoc.LoadFamily(familyPath, new FamilyLoadOption(), out var fam)) { ; } familySymbol = familyDoc.GetElement(fam.GetFamilySymbolIds().First()) as DB.FamilySymbol; } else { if (Doc.LoadFamily(familyPath, new FamilyLoadOption(), out var fam)) { familySymbol = Doc.GetElement(fam.GetFamilySymbolIds().First()) as DB.FamilySymbol; } } familySymbol.Activate(); //File.Delete(familyPath); } // see if this is a nested family instance or to be inserted in project FamilyInstance _instance = null; if (familyDoc != null) { _instance = familyDoc.FamilyCreate.NewFamilyInstance(basePoint, familySymbol, DB.Structure.StructuralType.NonStructural); familyDoc.Regenerate(); } else { _instance = Doc.Create.NewFamilyInstance(basePoint, familySymbol, DB.Structure.StructuralType.NonStructural); Doc.Regenerate(); } // transform if (_instance != null) { if (MatrixDecompose(instance.transform, out double rotation)) { try { // some point based families don't have a rotation, so keep this in a try catch if (rotation != (_instance.Location as LocationPoint).Rotation) { var axis = DB.Line.CreateBound(new XYZ(basePoint.X, basePoint.Y, 0), new XYZ(basePoint.X, basePoint.Y, 1000)); (_instance.Location as LocationPoint).Rotate(axis, rotation - (_instance.Location as LocationPoint).Rotation); } } catch { } } SetInstanceParameters(_instance, instance); result = "success"; } return(result); }