Skip to content

Commit

Permalink
fix(revit): extrusion roof and freeform elements conversion (#3045)
Browse files Browse the repository at this point in the history
* Update ConvertFreeformElement.cs

* fixes extrusion roof conversion

* Update ConvertRoof.cs
  • Loading branch information
clairekuang authored Nov 14, 2023
1 parent e780b2d commit 217fecb
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public ApplicationObject FreeformElementToNative(Objects.BuiltElements.Revit.Fre
appObj.Update(status: ApplicationObject.State.Failed);
return appObj;
}

Doc.LoadFamily(tempPath, new FamilyLoadOption(), out var fam);
var symbol = Doc.GetElement(fam.GetFamilySymbolIds().First()) as DB.FamilySymbol;
symbol.Activate();
Expand Down Expand Up @@ -186,10 +187,12 @@ private string CreateFreeformElementFamily(List<DB.Solid> solids, string name, o
t.Start();

//by default free form elements are always generic models
BuiltInCategory bic = BuiltInCategory.OST_GenericModel;
Category cat = famDoc.Settings.Categories.get_Item(bic);
Category cat = null;
if (freeformElement is not null && !string.IsNullOrEmpty(freeformElement.subcategory))
{
BuiltInCategory bic = BuiltInCategory.OST_GenericModel;
cat = famDoc.Settings.Categories.get_Item(bic);

//subcategory
if (cat.SubCategories.Contains(freeformElement.subcategory))
{
Expand All @@ -204,7 +207,10 @@ private string CreateFreeformElementFamily(List<DB.Solid> solids, string name, o
foreach (var s in solids)
{
var f = DB.FreeFormElement.Create(famDoc, s);
f.Subcategory = cat;
if (cat is not null)
{
f.Subcategory = cat;
}
}

t.Commit();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -743,9 +743,17 @@ public XYZ GetPerpendicular(XYZ xyz)
var xn = new XYZ(1, 0, 0);

if (ixn.IsAlmostEqualTo(xn))
{
xn = new XYZ(0, 1, 0);
}
else if (ixn.Negate().IsAlmostEqualTo(xn))
{
xn = new XYZ(0, -1, 0);
}

var cross = ixn.CrossProduct(xn);

return ixn.CrossProduct(xn).Normalize();
return cross.Normalize();
}

public Geometry.Surface FaceToSpeckle(DB.Face face, DB.BoundingBoxUV uvBox, Document doc, string units = null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,28 +29,35 @@ public ApplicationObject RoofToNative(Roof speckleRoof)
return appObj;
}

// outline is required for roofs, except for Extrusion roofs
CurveArray outline = null;
if (speckleRoof.outline is null)
// outline is required for footprint roofs
// referenceLine is required for for Extrusion roofs
CurveArray roofCurve = null;
if (speckleRoof is RevitExtrusionRoof extrusionRoof)
{
if (speckleRoof is not RevitExtrusionRoof)
if (extrusionRoof.referenceLine is null)
{
appObj.Update(status: ApplicationObject.State.Failed, logItem: "Roof outline was null");
appObj.Update(status: ApplicationObject.State.Failed, logItem: "Extrusion roof profile was null");
return appObj;
}
roofCurve = CurveToNative(extrusionRoof.referenceLine);
}
else
{
outline = CurveToNative(speckleRoof.outline);
if (speckleRoof.outline is null)
{
appObj.Update(status: ApplicationObject.State.Failed, logItem: "Roof outline was null");
return appObj;
}
roofCurve = CurveToNative(speckleRoof.outline);
}

// retrieve the level
var levelState = ApplicationObject.State.Unknown;
double baseOffset = 0.0;
DB.Level level = speckleRoof.level is not null
? ConvertLevelToRevit(speckleRoof.level, out levelState)
: outline is not null
? ConvertLevelToRevit(outline.get_Item(0), out levelState, out baseOffset)
: roofCurve is not null
? ConvertLevelToRevit(roofCurve.get_Item(0), out levelState, out baseOffset)
: null;

var speckleRevitRoof = speckleRoof as RevitRoof;
Expand All @@ -72,6 +79,7 @@ public ApplicationObject RoofToNative(Roof speckleRoof)
{
case RevitExtrusionRoof speckleExtrusionRoof:
{
// get the norm
var referenceLine = LineToNative(speckleExtrusionRoof.referenceLine);
var norm = GetPerpendicular(referenceLine.GetEndPoint(0) - referenceLine.GetEndPoint(1)).Negate();
ReferencePlane plane = Doc.Create.NewReferencePlane(
Expand All @@ -81,16 +89,10 @@ public ApplicationObject RoofToNative(Roof speckleRoof)
Doc.ActiveView
);

// get level if null
if (level is null)
{
level = ConvertLevelToRevit(referenceLine, out levelState, out baseOffset);
}

//create floor without a type
//create floor without a type with the profile
var start = ScaleToNative(speckleExtrusionRoof.start, speckleExtrusionRoof.units);
var end = ScaleToNative(speckleExtrusionRoof.end, speckleExtrusionRoof.units);
revitRoof = Doc.Create.NewExtrusionRoof(outline, plane, level, roofType, start, end);
revitRoof = Doc.Create.NewExtrusionRoof(roofCurve, plane, level, roofType, start, end);

// sometimes Revit flips the roof so the start offset is the end and vice versa.
// In that case, delete the created roof, flip the referencePlane and recreate it.
Expand All @@ -99,14 +101,14 @@ public ApplicationObject RoofToNative(Roof speckleRoof)
{
Doc.Delete(revitRoof.Id);
plane.Flip();
revitRoof = Doc.Create.NewExtrusionRoof(outline, plane, level, roofType, start, end);
revitRoof = Doc.Create.NewExtrusionRoof(roofCurve, plane, level, roofType, start, end);
}
break;
}
case RevitFootprintRoof speckleFootprintRoof:
{
ModelCurveArray curveArray = new ModelCurveArray();
var revitFootprintRoof = Doc.Create.NewFootPrintRoof(outline, level, roofType, out curveArray);
var revitFootprintRoof = Doc.Create.NewFootPrintRoof(roofCurve, level, roofType, out curveArray);

// if the roof is a curtain roof then set the mullions at the borders
var nestedElements = speckleFootprintRoof.elements;
Expand Down

0 comments on commit 217fecb

Please sign in to comment.