Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes for advanced brep export #559

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 25 additions & 14 deletions Source/Revit.IFC.Export/Exporter/BodyExporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1567,31 +1567,32 @@ public static IFCAnyHandle ExportBodyAsAdvancedBrep(ExporterIFC exporterIFC, Ele
{
return null;
}
Dictionary<EdgeArray, IList<EdgeArray>> sortedEdgeLoop = GeometryUtil.SortEdgeLoop(face.EdgeLoops, face);
var sortedEdgeLoop = GeometryUtil.GetOuterLoopsWithInnerLoops(face);

// check that we get back the same number of edgeloop
int numberOfSortedEdgeLoop = 0;
foreach (KeyValuePair<EdgeArray, IList<EdgeArray>> pair in sortedEdgeLoop)
foreach (var (outerLoop, innerLoops) in sortedEdgeLoop)
{
numberOfSortedEdgeLoop += 1 + pair.Value.Count;
numberOfSortedEdgeLoop += 1 + innerLoops.Count;
}

if (numberOfSortedEdgeLoop != face.EdgeLoops.Size)
{
return null;
}

foreach (KeyValuePair<EdgeArray, IList<EdgeArray>> pair in sortedEdgeLoop)
foreach (var (outerLoop, loops) in sortedEdgeLoop)
{
if (pair.Key == null || pair.Value == null)
if (outerLoop == null || loops == null)
return null;

HashSet<IFCAnyHandle> bounds = new HashSet<IFCAnyHandle>();

// Append the outerloop at the beginning of the list of inner loop
pair.Value.Insert(0, pair.Key);
loops.Insert(0, outerLoop);

// Process each inner loop
foreach (EdgeArray edgeArray in pair.Value)
foreach (EdgeArray edgeArray in loops)
{
// Map each edge in this loop back to its corresponding edge curve and then calculate its orientation to create IfcOrientedEdge
foreach (Edge edge in edgeArray)
Expand Down Expand Up @@ -1640,7 +1641,14 @@ public static IFCAnyHandle ExportBodyAsAdvancedBrep(ExporterIFC exporterIFC, Ele
if (edgeLoopList.Count == 1)
faceBound = IFCInstanceExporter.CreateFaceOuterBound(file, edgeLoop, true);
else
faceBound = IFCInstanceExporter.CreateFaceBound(file, edgeLoop, false);
{
//Outer loops go CCW around face normal, inner loops CW. Orientation flag on IfcFaceBound
//does not indicate this orientation. Rather, it indicates whether or not the loop is used
//by the face the way it was first created. Since we create a new IfcFaceBound for each revit
//face loop and since each revit loop is oriented w.r.t. the face normal as demanded by IFC,
//this is always the case.
faceBound = IFCInstanceExporter.CreateFaceBound(file, edgeLoop, true);
}

bounds.Add(faceBound);

Expand Down Expand Up @@ -1793,27 +1801,30 @@ public static IFCAnyHandle ExportBodyAsAdvancedBrep(ExporterIFC exporterIFC, Ele

// Set the base plane of the swept curve transform
Transform basePlaneTrf = Transform.Identity;
basePlaneTrf.BasisZ = zdir;
basePlaneTrf.BasisX = xDir;
basePlaneTrf.BasisY = zdir.CrossProduct(xDir);
var xDirIFC = ExporterIFCUtils.TransformAndScaleVector(exporterIFC, xDir);
var zDirIFC = ExporterIFCUtils.TransformAndScaleVector(exporterIFC, zdir);
basePlaneTrf.BasisZ = zDirIFC;
basePlaneTrf.BasisX = xDirIFC;
basePlaneTrf.BasisY = zDirIFC.CrossProduct(xDirIFC);

IList<double> locationOrds = IFCAnyHandleUtil.GetCoordinates(location);
basePlaneTrf.Origin = new XYZ(locationOrds[0], locationOrds[1], locationOrds[2]);

// Transform the dir to follow to the face transform
XYZ endsDiff = secondProfileCurve.GetEndPoint(0) - firstProfileCurve.GetEndPoint(0);

double depth = endsDiff.GetLength();
double depth = UnitUtil.ScaleLength(endsDiff.GetLength());

XYZ dir = endsDiff.Normalize();
if (dir == null || MathUtil.IsAlmostZero(dir.GetLength()))
{
// The extrusion direction is either null or too small to normalize
return null;
}
dir = basePlaneTrf.Inverse.OfVector(dir);
var dirIFC = ExporterIFCUtils.TransformAndScaleVector(exporterIFC, dir);
dirIFC = basePlaneTrf.Inverse.OfVector(dirIFC);

IFCAnyHandle direction = GeometryUtil.VectorToIfcDirection(exporterIFC, dir);
IFCAnyHandle direction = ExporterUtil.CreateDirection(file, dirIFC);
IFCAnyHandle sweptCurve = CreateProfileCurveFromCurve(file, exporterIFC, firstProfileCurve, Resources.RuledFaceProfileCurve, cartesianPoints, basePlaneTrf.Inverse);

surface = IFCInstanceExporter.CreateSurfaceOfLinearExtrusion(file, sweptCurve, sweptCurvePosition, direction, depth);
Expand Down
Loading