/// <summary> /// Creates a SimpleSweptSolidAnalyzer and computes the swept solid. /// </summary> /// <param name="faces">The faces of a solid.</param> /// <param name="normal">The normal of the reference plane that a path might lie on. If it is null, try to guess based on the geometry.</param> /// <returns>The analyzer.</returns> /// <remarks>This is a simple analyzer, and is not intended to be general - it works in some simple, real-world cases.</remarks> public static SimpleSweptSolidAnalyzer Create(ICollection <Face> faces, XYZ normal) { if (faces == null || faces.Count < 3) { throw new ArgumentException("Invalid faces.", "faces"); } if (normal == null) { foreach (Face face in faces) { if (face is RevolvedFace) { XYZ faceNormal = (face as RevolvedFace).Axis; if (normal == null) { normal = faceNormal; } else if (!MathUtil.VectorsAreParallel(normal, faceNormal)) { throw new InvalidOperationException("Couldn't calculate swept solid normal."); } } } } // find potential profile faces, their normal vectors must be orthogonal to the input normal List <PlanarFace> potentialSweepEndFaces = new List <PlanarFace>(); foreach (Face face in faces) { PlanarFace planarFace = face as PlanarFace; if (planarFace == null) { continue; } if (MathUtil.VectorsAreOrthogonal(normal, planarFace.FaceNormal)) { potentialSweepEndFaces.Add(planarFace); } } if (potentialSweepEndFaces.Count < 2) { // Can't find enough potential end faces. return(null); } int ii = 0; PlanarFace candidateProfileFace = null; // the potential profile face for the swept solid PlanarFace candidateProfileFace2 = null; Edge candidatePathEdge = null; bool foundCandidateFace = false; do { candidateProfileFace = potentialSweepEndFaces[ii++]; // find edges on the candidate profile face and the side faces with the edges // later find edges on the other candidate profile face with same side faces // they will be used to compare if the edges are congruent // to make sure the two faces are the potential profile faces Dictionary <Face, Edge> sideFacesWithCandidateEdges = new Dictionary <Face, Edge>(); EdgeArrayArray candidateFaceEdgeLoops = candidateProfileFace.EdgeLoops; foreach (EdgeArray edgeArray in candidateFaceEdgeLoops) { foreach (Edge candidateEdge in edgeArray) { Face sideFace = candidateEdge.GetFace(0); if (sideFace == candidateProfileFace) { sideFace = candidateEdge.GetFace(1); } if (sideFacesWithCandidateEdges.ContainsKey(sideFace)) // should not happen { throw new InvalidOperationException("Failed"); } sideFacesWithCandidateEdges[sideFace] = candidateEdge; } } double candidateProfileFaceArea = candidateProfileFace.Area; foreach (PlanarFace theOtherCandidateFace in potentialSweepEndFaces) { if (theOtherCandidateFace.Equals(candidateProfileFace)) { continue; } if (!MathUtil.IsAlmostEqual(candidateProfileFaceArea, theOtherCandidateFace.Area)) { continue; } EdgeArrayArray theOtherCandidateFaceEdgeLoops = theOtherCandidateFace.EdgeLoops; bool failToFindTheOtherCandidateFace = false; Dictionary <Face, Edge> sideFacesWithTheOtherCandidateEdges = new Dictionary <Face, Edge>(); foreach (EdgeArray edgeArray in theOtherCandidateFaceEdgeLoops) { foreach (Edge theOtherCandidateEdge in edgeArray) { Face sideFace = theOtherCandidateEdge.GetFace(0); if (sideFace == theOtherCandidateFace) { sideFace = theOtherCandidateEdge.GetFace(1); } if (!sideFacesWithCandidateEdges.ContainsKey(sideFace)) // should already have { failToFindTheOtherCandidateFace = true; break; } if (sideFacesWithTheOtherCandidateEdges.ContainsKey(sideFace)) // should not happen { throw new InvalidOperationException("Failed"); } sideFacesWithTheOtherCandidateEdges[sideFace] = theOtherCandidateEdge; } } if (failToFindTheOtherCandidateFace) { continue; } if (sideFacesWithCandidateEdges.Count != sideFacesWithTheOtherCandidateEdges.Count) { continue; } // side faces with candidate profile face edges Dictionary <Face, List <Edge> > sideFacesWithEdgesDic = new Dictionary <Face, List <Edge> >(); foreach (Face sideFace in sideFacesWithCandidateEdges.Keys) { sideFacesWithEdgesDic[sideFace] = new List <Edge>(); sideFacesWithEdgesDic[sideFace].Add(sideFacesWithCandidateEdges[sideFace]); sideFacesWithEdgesDic[sideFace].Add(sideFacesWithTheOtherCandidateEdges[sideFace]); } if (!AreFacesSimpleCongruent(sideFacesWithEdgesDic)) { continue; } // find candidate path edges Dictionary <Face, List <Edge> > candidatePathEdgesWithFace = new Dictionary <Face, List <Edge> >(); foreach (KeyValuePair <Face, List <Edge> > sideFaceAndEdges in sideFacesWithEdgesDic) { List <Edge> pathEdges = FindCandidatePathEdge(sideFaceAndEdges.Key, sideFaceAndEdges.Value[0], sideFaceAndEdges.Value[1]); // maybe we found two faces of an opening or a recess on the swept solid, skip in this case if (pathEdges.Count < 2) { failToFindTheOtherCandidateFace = true; break; } candidatePathEdgesWithFace[sideFaceAndEdges.Key] = pathEdges; } if (failToFindTheOtherCandidateFace) { continue; } // check if these edges are congruent if (!AreEdgesSimpleCongruent(candidatePathEdgesWithFace)) { continue; } candidatePathEdge = candidatePathEdgesWithFace.Values.ElementAt(0).ElementAt(0); foundCandidateFace = true; candidateProfileFace2 = theOtherCandidateFace; break; } if (foundCandidateFace) { break; } } while (ii < potentialSweepEndFaces.Count); SimpleSweptSolidAnalyzer simpleSweptSolidAnalyzer = null; if (foundCandidateFace) { simpleSweptSolidAnalyzer = new SimpleSweptSolidAnalyzer(); Curve pathCurve = candidatePathEdge.AsCurve(); XYZ endPoint0 = pathCurve.GetEndPoint(0); bool foundProfileFace = false; List <PlanarFace> profileFaces = new List <PlanarFace>(); profileFaces.Add(candidateProfileFace); profileFaces.Add(candidateProfileFace2); foreach (PlanarFace profileFace in profileFaces) { IntersectionResultArray intersectionResults; profileFace.Intersect(pathCurve, out intersectionResults); if (intersectionResults != null) { foreach (IntersectionResult intersectionResult in intersectionResults) { XYZ intersectPoint = intersectionResult.XYZPoint; if (intersectPoint.IsAlmostEqualTo(endPoint0)) { simpleSweptSolidAnalyzer.m_ProfileFace = profileFace; foundProfileFace = true; break; } } } if (foundProfileFace) { break; } } if (!foundProfileFace) { // Failed to find profile face. return(null); } // TODO: consider one profile face has an opening extrusion inside while the other does not List <Face> alignedFaces = FindAlignedFaces(profileFaces.ToList <Face>()); List <Face> unalignedFaces = new List <Face>(); foreach (Face face in faces) { if (profileFaces.Contains(face) || alignedFaces.Contains(face)) { continue; } unalignedFaces.Add(face); } simpleSweptSolidAnalyzer.m_UnalignedFaces = unalignedFaces; simpleSweptSolidAnalyzer.m_PathCurve = pathCurve; simpleSweptSolidAnalyzer.m_ReferencePlaneNormal = normal; } return(simpleSweptSolidAnalyzer); }
/// <summary> /// Creates a SimpleSweptSolidAnalyzer and computes the swept solid. This method should be used when a swept curve (directrix) is already known. Even when it is missing (null) /// it will simplu call the original one where it will try to determine the swept curve (directrix) using the connecting faces /// </summary> /// <param name="faces">The faces of a solid.</param> /// <param name="normal">The normal of the reference plane that a path might lie on. If it is null, try to guess based on the geometry.</param> /// <param name="potentialPathGeom">The potential swept path (e.g. in Revit MEP pipe/duct/fitting may already have this defined as part of the model)</param> /// <returns>The analyzer.</returns> /// <remarks>This is a simple analyzer, and is not intended to be general - it works in some simple, real-world cases.</remarks> public static SimpleSweptSolidAnalyzer Create(ICollection <Face> faces, XYZ normal, GeometryObject potentialPathGeom) { SimpleSweptSolidAnalyzer simpleSweptSolidAnalyzer = null; IList <Tuple <PlanarFace, XYZ> > potentialSweptAreaFaces = new List <Tuple <PlanarFace, XYZ> >(); Curve directrix = potentialPathGeom as Curve; bool pathGeomExists = potentialPathGeom != null; if (!pathGeomExists) { return(Create(faces, normal)); } // Collect plannar faces as candidates for the swept area foreach (Face face in faces) { if (!(face is PlanarFace)) { continue; } PlanarFace planarFace = face as PlanarFace; // Candidate face must be Orthogonal to the plane where the directrix curve is if (MathUtil.VectorsAreOrthogonal(normal, planarFace.FaceNormal)) { // We are also interested to get only end faces where the Curve intersect the Face at the same point as the Curve start or end point IntersectionResultArray intersectResults; if (planarFace.Intersect(directrix, out intersectResults) == SetComparisonResult.Overlap) { foreach (IntersectionResult res in intersectResults) { if (res.XYZPoint.IsAlmostEqualTo(directrix.GetEndPoint(0)) || res.XYZPoint.IsAlmostEqualTo(directrix.GetEndPoint(1))) { Tuple <PlanarFace, XYZ> potentialEndFaceAndPoint = new Tuple <PlanarFace, XYZ>(planarFace, res.XYZPoint); potentialSweptAreaFaces.Add(potentialEndFaceAndPoint); } } } } } // If there are more than 1 candidates, we need to find the congruent faces, and they cannot be on the same plane IList <Tuple <PlanarFace, XYZ> > sweptEndFaces = new List <Tuple <PlanarFace, XYZ> >(); while (potentialSweptAreaFaces.Count > 1) { bool foundPair = false; PlanarFace face0 = potentialSweptAreaFaces[0].Item1; XYZ ptDirectrix = potentialSweptAreaFaces[0].Item2; potentialSweptAreaFaces.RemoveAt(0); // remove the item from the List IList <Tuple <PlanarFace, XYZ> > potentialPairList = potentialSweptAreaFaces; foreach (Tuple <PlanarFace, XYZ> potentialPair in potentialPairList) { PlanarFace face1 = potentialPair.Item1; // Cannot handle faces that are on the same plane or intersecting (will cause self-intersection when being swept) // -- Can't do the intersection way because Revit returns intersection of the planes where those faces are defines (unbound) //if (face0.Intersect(face1) == FaceIntersectionFaceResult.Intersecting) // continue; // If the faces are facing the same direction (or opposite) they may be of the same plane. Skip those of the same plane if (face0.FaceNormal.IsAlmostEqualTo(face1.FaceNormal) || face0.FaceNormal.IsAlmostEqualTo(face1.FaceNormal.Negate())) { // chose any point in face0 and face1 XYZ pF0TopF1 = (face0.EdgeLoops.get_Item(0).get_Item(0).AsCurve().GetEndPoint(0) - face1.EdgeLoops.get_Item(0).get_Item(0).AsCurve().GetEndPoint(0)).Normalize(); if (pF0TopF1 == null || pF0TopF1.IsZeroLength()) { continue; } // If the vector created from a point in Face0 and a point in Face1 against the face normal is orthogonal, it means the faces are on the same plane if (MathUtil.VectorsAreOrthogonal(face0.FaceNormal, pF0TopF1)) { continue; } } if (AreFacesSimpleCongruent(face0, face1)) { sweptEndFaces.Add(new Tuple <PlanarFace, XYZ>(face0, ptDirectrix)); sweptEndFaces.Add(new Tuple <PlanarFace, XYZ>(face1, potentialPair.Item2)); foundPair = true; break; } } if (foundPair) { break; } } if (sweptEndFaces.Count >= 2) { simpleSweptSolidAnalyzer = new SimpleSweptSolidAnalyzer(); simpleSweptSolidAnalyzer.m_ProfileFace = sweptEndFaces[0].Item1; simpleSweptSolidAnalyzer.m_PathCurve = directrix; simpleSweptSolidAnalyzer.m_ReferencePlaneNormal = normal; } return(simpleSweptSolidAnalyzer); }
/// <summary> /// Creates a SimpleSweptSolidAnalyzer and computes the swept solid. /// </summary> /// <param name="faces">The faces of a solid.</param> /// <param name="normal">The normal of the reference plane that a path might lie on. If it is null, try to guess based on the geometry.</param> /// <returns>The analyzer.</returns> /// <remarks>This is a simple analyzer, and is not intended to be general - it works in some simple, real-world cases.</remarks> public static SimpleSweptSolidAnalyzer Create(ICollection<Face> faces, XYZ normal) { if (faces == null || faces.Count < 3) throw new ArgumentException("Invalid faces.", "faces"); if (normal == null) { foreach (Face face in faces) { if (face is RevolvedFace) { XYZ faceNormal = (face as RevolvedFace).Axis; if (normal == null) normal = faceNormal; else if (!MathUtil.VectorsAreParallel(normal, faceNormal)) throw new InvalidOperationException("Couldn't calculate swept solid normal."); } } } // find potential profile faces, their normal vectors must be orthogonal to the input normal List<PlanarFace> potentialSweepEndFaces = new List<PlanarFace>(); foreach (Face face in faces) { PlanarFace planarFace = face as PlanarFace; if (planarFace == null) continue; if (MathUtil.VectorsAreOrthogonal(normal, planarFace.Normal)) potentialSweepEndFaces.Add(planarFace); } if (potentialSweepEndFaces.Count < 2) throw new InvalidOperationException("Can't find enough potential end faces."); int i = 0; PlanarFace candidateProfileFace = null; // the potential profile face for the swept solid PlanarFace candidateProfileFace2 = null; Edge candidatePathEdge = null; bool foundCandidateFace = false; do { candidateProfileFace = potentialSweepEndFaces[i++]; // find edges on the candidate profile face and the side faces with the edges // later find edges on the other candidate profile face with same side faces // they will be used to compare if the edges are congruent // to make sure the two faces are the potential profile faces Dictionary<Face, Edge> sideFacesWithCandidateEdges = new Dictionary<Face, Edge>(); EdgeArrayArray candidateFaceEdgeLoops = candidateProfileFace.EdgeLoops; foreach (EdgeArray edgeArray in candidateFaceEdgeLoops) { foreach (Edge candidateEdge in edgeArray) { Face sideFace = candidateEdge.GetFace(0); if (sideFace == candidateProfileFace) sideFace = candidateEdge.GetFace(1); if (sideFacesWithCandidateEdges.ContainsKey(sideFace)) // should not happen throw new InvalidOperationException("Failed"); sideFacesWithCandidateEdges[sideFace] = candidateEdge; } } double candidateProfileFaceArea = candidateProfileFace.Area; foreach (PlanarFace theOtherCandidateFace in potentialSweepEndFaces) { if (theOtherCandidateFace.Equals(candidateProfileFace)) continue; if (!MathUtil.IsAlmostEqual(candidateProfileFaceArea, theOtherCandidateFace.Area)) continue; EdgeArrayArray theOtherCandidateFaceEdgeLoops = theOtherCandidateFace.EdgeLoops; bool failToFindTheOtherCandidateFace = false; Dictionary<Face, Edge> sideFacesWithTheOtherCandidateEdges = new Dictionary<Face, Edge>(); foreach (EdgeArray edgeArray in theOtherCandidateFaceEdgeLoops) { foreach (Edge theOtherCandidateEdge in edgeArray) { Face sideFace = theOtherCandidateEdge.GetFace(0); if (sideFace == theOtherCandidateFace) sideFace = theOtherCandidateEdge.GetFace(1); if (!sideFacesWithCandidateEdges.ContainsKey(sideFace)) // should already have { failToFindTheOtherCandidateFace = true; break; } if (sideFacesWithTheOtherCandidateEdges.ContainsKey(sideFace)) // should not happen throw new InvalidOperationException("Failed"); sideFacesWithTheOtherCandidateEdges[sideFace] = theOtherCandidateEdge; } } if (failToFindTheOtherCandidateFace) continue; if (sideFacesWithCandidateEdges.Count != sideFacesWithTheOtherCandidateEdges.Count) continue; // side faces with candidate profile face edges Dictionary<Face, List<Edge>> sideFacesWithEdgesDic = new Dictionary<Face, List<Edge>>(); foreach (Face sideFace in sideFacesWithCandidateEdges.Keys) { sideFacesWithEdgesDic[sideFace] = new List<Edge>(); sideFacesWithEdgesDic[sideFace].Add(sideFacesWithCandidateEdges[sideFace]); sideFacesWithEdgesDic[sideFace].Add(sideFacesWithTheOtherCandidateEdges[sideFace]); } if (!AreFacesSimpleCongruent(sideFacesWithEdgesDic)) continue; // find candidate path edges Dictionary<Face, List<Edge>> candidatePathEdgesWithFace = new Dictionary<Face, List<Edge>>(); foreach (KeyValuePair<Face, List<Edge>> sideFaceAndEdges in sideFacesWithEdgesDic) { List<Edge> pathEdges = FindCandidatePathEdge(sideFaceAndEdges.Key, sideFaceAndEdges.Value[0], sideFaceAndEdges.Value[1]); // maybe we found two faces of an opening or a recess on the swept solid, skip in this case if (pathEdges.Count < 2) { failToFindTheOtherCandidateFace = true; break; } candidatePathEdgesWithFace[sideFaceAndEdges.Key] = pathEdges; } if (failToFindTheOtherCandidateFace) continue; // check if these edges are congruent if (!AreEdgesSimpleCongruent(candidatePathEdgesWithFace)) continue; candidatePathEdge = candidatePathEdgesWithFace.Values.ElementAt(0).ElementAt(0); foundCandidateFace = true; candidateProfileFace2 = theOtherCandidateFace; break; } if (foundCandidateFace) break; } while (i < potentialSweepEndFaces.Count); SimpleSweptSolidAnalyzer simpleSweptSolidAnalyzer = null; if (foundCandidateFace) { simpleSweptSolidAnalyzer = new SimpleSweptSolidAnalyzer(); Curve pathCurve = candidatePathEdge.AsCurve(); XYZ endPoint0 = pathCurve.GetEndPoint(0); bool foundProfileFace = false; List<PlanarFace> profileFaces = new List<PlanarFace>(); profileFaces.Add(candidateProfileFace); profileFaces.Add(candidateProfileFace2); foreach (PlanarFace profileFace in profileFaces) { IntersectionResultArray intersectionResults; profileFace.Intersect(pathCurve, out intersectionResults); if (intersectionResults != null) { foreach (IntersectionResult intersectoinResult in intersectionResults) { XYZ intersectPoint = intersectoinResult.XYZPoint; if (intersectPoint.IsAlmostEqualTo(endPoint0)) { simpleSweptSolidAnalyzer.m_ProfileFace = profileFace; foundProfileFace = true; break; } } } if (foundProfileFace) break; } if (!foundProfileFace) throw new InvalidOperationException("Failed to find profile face."); // TODO: consider one profile face has an opening extrusion inside while the other does not List<Face> alignedFaces = FindAlignedFaces(profileFaces.ToList<Face>()); List<Face> unalignedFaces = new List<Face>(); foreach (Face face in faces) { if (profileFaces.Contains(face) || alignedFaces.Contains(face)) continue; unalignedFaces.Add(face); } simpleSweptSolidAnalyzer.m_UnalignedFaces = unalignedFaces; simpleSweptSolidAnalyzer.m_PathCurve = pathCurve; simpleSweptSolidAnalyzer.m_ReferencePlaneNormal = normal; } return simpleSweptSolidAnalyzer; }
/// <summary> /// Creates a SweptSolidExporter. /// </summary> /// <param name="exporterIFC">The exporter.</param> /// <param name="element">The element.</param> /// <param name="solid">The solid.</param> /// <param name="normal">The normal of the plane that the path lies on.</param> /// <returns>The SweptSolidExporter.</returns> public static SweptSolidExporter Create(ExporterIFC exporterIFC, Element element, SimpleSweptSolidAnalyzer sweptAnalyzer, GeometryObject geomObject) { try { if (sweptAnalyzer == null) return null; SweptSolidExporter sweptSolidExporter = null; IList<Revit.IFC.Export.Utility.GeometryUtil.FaceBoundaryType> faceBoundaryTypes; IList<CurveLoop> faceBoundaries = GeometryUtil.GetFaceBoundaries(sweptAnalyzer.ProfileFace, null, out faceBoundaryTypes); string profileName = null; if (element != null) { ElementType type = element.Document.GetElement(element.GetTypeId()) as ElementType; if (type != null) profileName = type.Name; } // Is it really an extrusion? if (sweptAnalyzer.PathCurve is Line) { Line line = sweptAnalyzer.PathCurve as Line; // invalid case if (MathUtil.VectorsAreOrthogonal(line.Direction, sweptAnalyzer.ProfileFace.FaceNormal)) return null; sweptSolidExporter = new SweptSolidExporter(); sweptSolidExporter.RepresentationType = ShapeRepresentationType.SweptSolid; Plane plane = new Plane(sweptAnalyzer.ProfileFace.FaceNormal, sweptAnalyzer.ProfileFace.Origin); sweptSolidExporter.RepresentationItem = ExtrusionExporter.CreateExtrudedSolidFromCurveLoop(exporterIFC, profileName, faceBoundaries, plane, line.Direction, UnitUtil.ScaleLength(line.Length)); } else { sweptSolidExporter = new SweptSolidExporter(); if (ExporterCacheManager.ExportOptionsCache.ExportAs4) { // Use tessellated geometry in IFC Reference View if (ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView) { // TODO: Create CreateSimpleSweptSolidAsTessellation routine that takes advantage of the superior tessellation of this class. BodyExporterOptions options = new BodyExporterOptions(false); sweptSolidExporter.RepresentationItem = BodyExporter.ExportBodyAsTriangulatedFaceSet(exporterIFC, element, options, geomObject); sweptSolidExporter.RepresentationType = ShapeRepresentationType.Tessellation; } else { sweptSolidExporter.RepresentationItem = CreateSimpleSweptSolid(exporterIFC, profileName, faceBoundaries, sweptAnalyzer.ReferencePlaneNormal, sweptAnalyzer.PathCurve); sweptSolidExporter.RepresentationType = ShapeRepresentationType.AdvancedSweptSolid; } } else { sweptSolidExporter.Facets = CreateSimpleSweptSolidAsBRep(exporterIFC, profileName, faceBoundaries, sweptAnalyzer.ReferencePlaneNormal, sweptAnalyzer.PathCurve); sweptSolidExporter.RepresentationType = ShapeRepresentationType.Brep; } } return sweptSolidExporter; } catch (Exception) { return null; } }
/// <summary> /// Creates a SweptSolidExporter. /// </summary> /// <param name="exporterIFC">The exporter.</param> /// <param name="element">The element.</param> /// <param name="solid">The solid.</param> /// <param name="normal">The normal of the plane that the path lies on.</param> /// <returns>The SweptSolidExporter.</returns> public static SweptSolidExporter Create(ExporterIFC exporterIFC, Element element, SimpleSweptSolidAnalyzer sweptAnalyzer) { try { if (sweptAnalyzer == null) return null; SweptSolidExporter sweptSolidExporter = null; IList<Revit.IFC.Export.Utility.GeometryUtil.FaceBoundaryType> faceBoundaryTypes; IList<CurveLoop> faceBoundaries = GeometryUtil.GetFaceBoundaries(sweptAnalyzer.ProfileFace, null, out faceBoundaryTypes); string profileName = null; if (element != null) { ElementType type = element.Document.GetElement(element.GetTypeId()) as ElementType; if (type != null) profileName = type.Name; } // Is it really an extrusion? if (sweptAnalyzer.PathCurve is Line) { Line line = sweptAnalyzer.PathCurve as Line; // invalid case if (MathUtil.VectorsAreOrthogonal(line.Direction, sweptAnalyzer.ProfileFace.Normal)) return null; sweptSolidExporter = new SweptSolidExporter(); sweptSolidExporter.m_IsExtrusion = true; Plane plane = new Plane(sweptAnalyzer.ProfileFace.Normal, sweptAnalyzer.ProfileFace.Origin); sweptSolidExporter.m_RepresentationItem = ExtrusionExporter.CreateExtrudedSolidFromCurveLoop(exporterIFC, profileName, faceBoundaries, plane, line.Direction, UnitUtil.ScaleLength(line.Length)); } else { sweptSolidExporter = new SweptSolidExporter(); if (ExporterCacheManager.ExportOptionsCache.ExportAs4) sweptSolidExporter.m_RepresentationItem = CreateSimpleSweptSolid(exporterIFC, profileName, faceBoundaries, sweptAnalyzer.ReferencePlaneNormal, sweptAnalyzer.PathCurve); else sweptSolidExporter.m_Facets = CreateSimpleSweptSolidAsBRep(exporterIFC, profileName, faceBoundaries, sweptAnalyzer.ReferencePlaneNormal, sweptAnalyzer.PathCurve); } return sweptSolidExporter; } catch (Exception) { return null; } }