/// <summary>
        /// Creates or updates the IfcLocalPlacement associated with the current origin offset.
        /// </summary>
        /// <param name="exporterIFC">The exporter.</param>
        /// <param name="bbox">The bounding box.</param>
        /// <param name="ecData">The extrusion creation data which contains the local placement.</param>
        /// <param name="lpOrig">The local placement origin.</param>
        /// <param name="unscaledTrfOrig">The unscaled local placement origin.</param>
        public void CreateLocalPlacementFromOffset(ExporterIFC exporterIFC, BoundingBoxXYZ bbox, IFCExtrusionCreationData ecData, XYZ lpOrig, XYZ unscaledTrfOrig)
        {
            if (ecData == null)
            {
                return;
            }

            IFCAnyHandle localPlacement = ecData.GetLocalPlacement();

            if (!IFCAnyHandleUtil.IsNullOrHasNoValue(localPlacement))
            {
                IFCFile file = exporterIFC.GetFile();

                // If the BBox passes through (0,0, 0), or no bbox, do nothing.
                if (bbox == null ||
                    ((bbox.Min.X < MathUtil.Eps() && bbox.Max.X > -MathUtil.Eps()) &&
                     (bbox.Min.Y < MathUtil.Eps() && bbox.Max.Y > -MathUtil.Eps()) &&
                     (bbox.Min.Z < MathUtil.Eps() && bbox.Max.Z > -MathUtil.Eps())))
                {
                    if (!ecData.ReuseLocalPlacement)
                    {
                        ecData.SetLocalPlacement(ExporterUtil.CopyLocalPlacement(file, localPlacement));
                    }
                    return;
                }

                if (!MathUtil.IsAlmostZero(unscaledTrfOrig.DotProduct(unscaledTrfOrig)))
                {
                    if (!ecData.ReuseLocalPlacement)
                    {
                        ecData.SetLocalPlacement(ExporterUtil.CreateLocalPlacement(file, localPlacement, lpOrig, null, null));
                    }
                    else
                    {
                        IFCAnyHandle relativePlacement = GeometryUtil.GetRelativePlacementFromLocalPlacement(localPlacement);
                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(relativePlacement))
                        {
                            IFCAnyHandle newRelativePlacement = ExporterUtil.CreateAxis(file, lpOrig, null, null);
                            GeometryUtil.SetRelativePlacement(localPlacement, newRelativePlacement);
                        }
                        else
                        {
                            IFCAnyHandle newOriginHnd = ExporterUtil.CreateCartesianPoint(file, lpOrig);
                            IFCAnyHandleUtil.SetAttribute(relativePlacement, "Location", newOriginHnd);
                        }
                    }
                }
                else if (ecData.ForceOffset)
                {
                    ecData.SetLocalPlacement(ExporterUtil.CreateLocalPlacement(file, localPlacement, null));
                }
                else if (!ecData.ReuseLocalPlacement)
                {
                    ecData.SetLocalPlacement(ExporterUtil.CopyLocalPlacement(file, localPlacement));
                }
            }
        }
        private static IFCAnyHandle CopyRailingHandle(ExporterIFC exporterIFC, Element elem, ElementId catId, IFCAnyHandle origLocalPlacement,
                                                      IFCAnyHandle origRailing)
        {
            IFCFile file = exporterIFC.GetFile();

            IFCAnyHandle origRailingObjectPlacement = IFCAnyHandleUtil.GetInstanceAttribute(origRailing, "ObjectPlacement");
            IFCAnyHandle railingRelativePlacement   = IFCAnyHandleUtil.GetInstanceAttribute(origRailingObjectPlacement, "RelativePlacement");
            IFCAnyHandle parentRelativePlacement    = IFCAnyHandleUtil.GetInstanceAttribute(origLocalPlacement, "RelativePlacement");

            IFCAnyHandle newRelativePlacement = null;
            IFCAnyHandle parentRelativeOrig   = IFCAnyHandleUtil.GetInstanceAttribute(parentRelativePlacement, "Location");

            if (!IFCAnyHandleUtil.IsNullOrHasNoValue(parentRelativeOrig))
            {
                IList <double> parentVec           = IFCAnyHandleUtil.GetCoordinates(parentRelativeOrig);
                IFCAnyHandle   railingRelativeOrig = IFCAnyHandleUtil.GetInstanceAttribute(railingRelativePlacement, "Location");
                if (!IFCAnyHandleUtil.IsNullOrHasNoValue(railingRelativeOrig))
                {
                    IList <double> railingVec = IFCAnyHandleUtil.GetCoordinates(railingRelativeOrig);

                    IList <double> newMeasure = new List <double>();
                    newMeasure.Add(railingVec[0] - parentVec[0]);
                    newMeasure.Add(railingVec[1] - parentVec[1]);
                    newMeasure.Add(railingVec[2]);

                    IFCAnyHandle locPtHnd = ExporterUtil.CreateCartesianPoint(file, newMeasure);
                    newRelativePlacement = IFCInstanceExporter.CreateAxis2Placement3D(file, locPtHnd, null, null);
                }
                else
                {
                    IList <double> railingMeasure = new List <double>();
                    railingMeasure.Add(-parentVec[0]);
                    railingMeasure.Add(-parentVec[1]);
                    railingMeasure.Add(0.0);
                    IFCAnyHandle locPtHnd = ExporterUtil.CreateCartesianPoint(file, railingMeasure);
                    newRelativePlacement = IFCInstanceExporter.CreateAxis2Placement3D(file, locPtHnd, null, null);
                }
            }

            IFCAnyHandle newLocalPlacement = IFCInstanceExporter.CreateLocalPlacement(file, origLocalPlacement, newRelativePlacement);
            IFCAnyHandle origRailingRep    = IFCAnyHandleUtil.GetInstanceAttribute(origRailing, "Representation");
            IFCAnyHandle newProdRep        = ExporterUtil.CopyProductDefinitionShape(exporterIFC, elem, catId, origRailingRep);

            string         ifcEnumTypeAsString = IFCAnyHandleUtil.GetEnumerationAttribute(origRailing, "PredefinedType");
            IFCRailingType railingType         = GetIFCRailingTypeFromString(ifcEnumTypeAsString);

            string       copyGUID         = GUIDUtil.CreateGUID();
            IFCAnyHandle copyOwnerHistory = IFCAnyHandleUtil.GetInstanceAttribute(origRailing, "OwnerHistory");
            string       copyName         = IFCAnyHandleUtil.GetStringAttribute(origRailing, "Name");
            string       copyDescription  = IFCAnyHandleUtil.GetStringAttribute(origRailing, "Description");
            string       copyObjectType   = IFCAnyHandleUtil.GetStringAttribute(origRailing, "ObjectType");
            string       copyElemId       = IFCAnyHandleUtil.GetStringAttribute(origRailing, "Tag");

            return(IFCInstanceExporter.CreateRailing(file, copyGUID, copyOwnerHistory, copyName, copyDescription, copyObjectType,
                                                     newLocalPlacement, newProdRep,
                                                     copyElemId, railingType));
        }
Exemple #3
0
 public static IFCAnyHandle GetDefaultCartesianTransformationOperator3D(IFCFile file)
 {
     if (m_DefaultCartesianTransformationOperator3D == null)
     {
         XYZ          orig    = new XYZ();
         IFCAnyHandle origHnd = ExporterUtil.CreateCartesianPoint(file, orig);
         m_DefaultCartesianTransformationOperator3D = IFCInstanceExporter.CreateCartesianTransformationOperator3D(file, null, null, origHnd, 1.0, null);
     }
     return(m_DefaultCartesianTransformationOperator3D);
 }
        private static IFCAnyHandle ExportBoundingBoxBase(ExporterIFC exporterIFC, XYZ cornerXYZ, double xDim, double yDim, double zDim)
        {
            double eps = MathUtil.Eps();

            if (xDim < eps || yDim < eps || zDim < eps)
            {
                return(null);
            }

            IFCFile      file            = exporterIFC.GetFile();
            IFCAnyHandle cornerHnd       = ExporterUtil.CreateCartesianPoint(file, cornerXYZ);
            IFCAnyHandle boundingBoxItem = IFCInstanceExporter.CreateBoundingBox(file, cornerHnd, xDim, yDim, zDim);

            if (IFCAnyHandleUtil.IsNullOrHasNoValue(boundingBoxItem))
            {
                return(null);
            }

            IFCAnyHandle contextOfItems = exporterIFC.Get3DContextHandle("Box");

            return(RepresentationUtil.CreateBoundingBoxRep(exporterIFC, contextOfItems, boundingBoxItem));
        }
Exemple #5
0
        /// <summary>
        /// Creates a facetation of a simple swept solid from a list of curve loops.
        /// </summary>
        /// <param name="exporterIFC">The exporter.</param>
        /// <param name="profileName">The profile name.</param>
        /// <param name="profileCurveLoops">The profile curve loops.</param>
        /// <param name="normal">The normal of the plane that the path lies on.</param>
        /// <param name="directrix">The path curve.</param>
        /// <returns>The list of facet handles.</returns>
        public static HashSet <IFCAnyHandle> CreateSimpleSweptSolidAsBRep(ExporterIFC exporterIFC, string profileName, IList <CurveLoop> profileCurveLoops,
                                                                          XYZ normal, Curve directrix)
        {
            // see definition of IfcSurfaceCurveSweptAreaSolid from
            // http://www.buildingsmart-tech.org/ifc/IFC2x4/rc4/html/schema/ifcgeometricmodelresource/lexical/ifcsurfacecurvesweptareasolid.htm

            HashSet <IFCAnyHandle> facetHnds = null;

            if (!CanCreateSimpleSweptSolid(profileCurveLoops, normal, directrix))
            {
                return(facetHnds);
            }

            // An extra requirement, as we can't tessellate an unbound curve.
            if (!directrix.IsBound)
            {
                return(facetHnds);
            }
            double originalStartParam = directrix.GetEndParameter(0);

            Plane axisPlane, profilePlane;

            CreateAxisAndProfileCurvePlanes(directrix, originalStartParam, out axisPlane, out profilePlane);

            IList <CurveLoop> curveLoops = null;

            try
            {
                // Check that curve loops are valid.
                curveLoops = ExporterIFCUtils.ValidateCurveLoops(profileCurveLoops, profilePlane.Normal);
            }
            catch (Exception)
            {
                return(null);
            }

            if (curveLoops == null || curveLoops.Count == 0)
            {
                return(facetHnds);
            }

            // Tessellate the curve loops.  We don't add the last point, as these should all be closed curves.
            IList <IList <XYZ> > tessellatedOutline = new List <IList <XYZ> >();

            foreach (CurveLoop curveLoop in curveLoops)
            {
                List <XYZ> tessellatedCurve = new List <XYZ>();
                foreach (Curve curve in curveLoop)
                {
                    if (curve is Line)
                    {
                        AddScaledPointToList(exporterIFC, tessellatedCurve, curve.GetEndPoint(0));
                    }
                    else
                    {
                        IList <XYZ> curveTessellation = CreateRoughTessellation(exporterIFC, curve);
                        tessellatedCurve.AddRange(curveTessellation);
                    }
                }

                if (tessellatedCurve.Count != 0)
                {
                    tessellatedOutline.Add(tessellatedCurve);
                }
            }

            IFCFile file = exporterIFC.GetFile();

            IList <IList <IList <IFCAnyHandle> > > facetVertexHandles = new List <IList <IList <IFCAnyHandle> > >();

            IList <IList <IFCAnyHandle> > tessellatedOutlineHandles = new List <IList <IFCAnyHandle> >();

            foreach (IList <XYZ> tessellatedOutlinePolygon in tessellatedOutline)
            {
                IList <IFCAnyHandle> tessellatedOutlinePolygonHandles = new List <IFCAnyHandle>();
                foreach (XYZ tessellatedOutlineXYZ in tessellatedOutlinePolygon)
                {
                    tessellatedOutlinePolygonHandles.Add(ExporterUtil.CreateCartesianPoint(file, tessellatedOutlineXYZ));
                }
                tessellatedOutlineHandles.Add(tessellatedOutlinePolygonHandles);
            }
            facetVertexHandles.Add(tessellatedOutlineHandles);

            // Tessellate the Directrix.  This only works for bound Directrix curves. Unfortunately, we get XYZ values, which we will have to convert
            // back to parameter values to get the local transform.
            IList <double> tessellatedDirectrixParameters = CreateRoughParametricTessellation(directrix);

            // Create all of the other outlines by transformng the first tessellated outline to the current transform.
            Transform profilePlaneTrf = Transform.CreateTranslation(ExporterIFCUtils.TransformAndScalePoint(exporterIFC, profilePlane.Origin));

            profilePlaneTrf.BasisX = ExporterIFCUtils.TransformAndScaleVector(exporterIFC, profilePlane.XVec);
            profilePlaneTrf.BasisY = ExporterIFCUtils.TransformAndScaleVector(exporterIFC, profilePlane.YVec);
            profilePlaneTrf.BasisZ = ExporterIFCUtils.TransformAndScaleVector(exporterIFC, profilePlane.Normal);

            // The inverse transform will be applied to generate the delta transform for the profile curves from the start of the directrix
            // to the current location.  This could be optimized in the case of a Line, but current usage is really only for a single arc.
            // If that changes, we should revisit optimization possibilities.
            Transform profilePlaneTrfInverse = profilePlaneTrf.Inverse;

            // Create the delta transforms and the offset tessellated profiles.
            foreach (double parameter in tessellatedDirectrixParameters)
            {
                Transform directrixDirs  = CreateProfileCurveTransform(exporterIFC, directrix, parameter);
                Transform deltaTransform = directrixDirs.Multiply(profilePlaneTrfInverse);

                IList <IList <IFCAnyHandle> > currTessellatedOutline = new List <IList <IFCAnyHandle> >();
                foreach (IList <XYZ> pointLoop in tessellatedOutline)
                {
                    IList <IFCAnyHandle> currTessellatedPoinLoop = new List <IFCAnyHandle>();
                    foreach (XYZ point in pointLoop)
                    {
                        XYZ          transformedPoint       = deltaTransform.OfPoint(point);
                        IFCAnyHandle transformedPointHandle = ExporterUtil.CreateCartesianPoint(file, transformedPoint);
                        currTessellatedPoinLoop.Add(transformedPointHandle);
                    }
                    currTessellatedOutline.Add(currTessellatedPoinLoop);
                }
                facetVertexHandles.Add(currTessellatedOutline);
            }

            // Create the side facets.
            facetHnds = new HashSet <IFCAnyHandle>();

            int numFacets = facetVertexHandles.Count - 1;

            for (int ii = 0; ii < numFacets; ii++)
            {
                IList <IList <IFCAnyHandle> > firstOutline  = facetVertexHandles[ii];
                IList <IList <IFCAnyHandle> > secondOutline = facetVertexHandles[ii + 1];

                int numLoops = firstOutline.Count;
                for (int jj = 0; jj < numLoops; jj++)
                {
                    IList <IFCAnyHandle> firstLoop  = firstOutline[jj];
                    IList <IFCAnyHandle> secondLoop = secondOutline[jj];

                    int numVertices = firstLoop.Count;

                    for (int kk = 0; kk < numVertices; kk++)
                    {
                        IList <IFCAnyHandle> polyLoopHandles = new List <IFCAnyHandle>(4);
                        polyLoopHandles.Add(secondLoop[kk]);
                        polyLoopHandles.Add(secondLoop[(kk + 1) % numVertices]);
                        polyLoopHandles.Add(firstLoop[(kk + 1) % numVertices]);
                        polyLoopHandles.Add(firstLoop[kk]);

                        IFCAnyHandle face = BodyExporter.CreateFaceFromVertexList(file, polyLoopHandles);
                        facetHnds.Add(face);
                    }
                }
            }

            // Create the end facets.
            for (int ii = 0; ii < 2; ii++)
            {
                int faceIndex = (ii == 0) ? 0 : facetVertexHandles.Count - 1;

                int numLoops = facetVertexHandles[faceIndex].Count;
                HashSet <IFCAnyHandle> faceBounds = new HashSet <IFCAnyHandle>();

                for (int jj = 0; jj < numLoops; jj++)
                {
                    IList <IFCAnyHandle> polyLoopHandles = null;
                    if (ii == 0)
                    {
                        polyLoopHandles = facetVertexHandles[faceIndex][jj];
                    }
                    else
                    {
                        int numHandles = facetVertexHandles[faceIndex][jj].Count;
                        polyLoopHandles = new List <IFCAnyHandle>(numHandles);
                        for (int kk = numHandles - 1; kk >= 0; kk--)
                        {
                            polyLoopHandles.Add(facetVertexHandles[faceIndex][jj][kk]);
                        }
                    }

                    IFCAnyHandle polyLoop  = IFCInstanceExporter.CreatePolyLoop(file, polyLoopHandles);
                    IFCAnyHandle faceBound = (jj == 0) ?
                                             IFCInstanceExporter.CreateFaceOuterBound(file, polyLoop, true) :
                                             IFCInstanceExporter.CreateFaceBound(file, polyLoop, true);
                    faceBounds.Add(faceBound);
                }

                IFCAnyHandle face = IFCInstanceExporter.CreateFace(file, faceBounds);
                facetHnds.Add(face);
            }

            return(facetHnds);
        }
        /// <summary>
        ///    Initializes the transformation in the transform setter.
        /// </summary>
        /// <param name="exporterIFC">The exporter.</param>
        /// <param name="geometryList">The set of geometry used to determine the bounding box.</param>
        /// <param name="ecData">The extrusion creation data which contains the local placement.</param>
        /// <returns>The transform corresponding to the movement, if any.</returns>
        /// <remarks>This method will eventually be obsoleted by the InitializeFromBoundingBox/CreateLocalPlacementFromOffset pair below, which delays creating or updating the local placement
        /// until we are certain we will use it, saving time and reducing wasted line numbers.</remarks>
        public Transform InitializeFromBoundingBox(ExporterIFC exporterIFC, IList <GeometryObject> geometryList, IFCExtrusionCreationData ecData)
        {
            if (ecData == null)
            {
                return(null);
            }
            Transform trf = Transform.Identity;

            IFCAnyHandle localPlacement = ecData.GetLocalPlacement();

            if (!IFCAnyHandleUtil.IsNullOrHasNoValue(localPlacement))
            {
                IFCFile        file = exporterIFC.GetFile();
                BoundingBoxXYZ bbox = GeometryUtil.GetBBoxOfGeometries(geometryList);

                // If the BBox passes through (0,0, 0), or no bbox, do nothing.
                if (bbox == null ||
                    ((bbox.Min.X < MathUtil.Eps() && bbox.Max.X > -MathUtil.Eps()) &&
                     (bbox.Min.Y < MathUtil.Eps() && bbox.Max.Y > -MathUtil.Eps()) &&
                     (bbox.Min.Z < MathUtil.Eps() && bbox.Max.Z > -MathUtil.Eps())))
                {
                    if (!ecData.ReuseLocalPlacement)
                    {
                        ecData.SetLocalPlacement(ExporterUtil.CopyLocalPlacement(file, localPlacement));
                    }
                    return(trf);
                }

                XYZ bboxMin    = bbox.Min;
                XYZ scaledOrig = UnitUtil.ScaleLength(bboxMin);

                Transform scaledTrf = GeometryUtil.GetScaledTransform(exporterIFC);

                XYZ lpOrig = scaledTrf.OfPoint(scaledOrig);
                if (!ecData.AllowVerticalOffsetOfBReps)
                {
                    lpOrig = new XYZ(lpOrig.X, lpOrig.Y, 0.0);
                }

                Transform scaledTrfInv  = scaledTrf.Inverse;
                XYZ       scaledInvOrig = scaledTrfInv.OfPoint(XYZ.Zero);

                XYZ unscaledInvOrig = UnitUtil.UnscaleLength(scaledInvOrig);

                XYZ trfOrig = unscaledInvOrig - bboxMin;
                if (!ecData.AllowVerticalOffsetOfBReps)
                {
                    trfOrig = new XYZ(trfOrig.X, trfOrig.Y, 0.0);
                }

                if (!MathUtil.IsAlmostZero(trfOrig.DotProduct(trfOrig)))
                {
                    Initialize(exporterIFC, trfOrig, XYZ.BasisX, XYZ.BasisY);
                    if (!ecData.ReuseLocalPlacement)
                    {
                        ecData.SetLocalPlacement(ExporterUtil.CreateLocalPlacement(file, localPlacement, lpOrig, null, null));
                    }
                    else
                    {
                        IFCAnyHandle relativePlacement = GeometryUtil.GetRelativePlacementFromLocalPlacement(localPlacement);
                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(relativePlacement))
                        {
                            IFCAnyHandle newRelativePlacement = ExporterUtil.CreateAxis(file, lpOrig, null, null);
                            GeometryUtil.SetRelativePlacement(localPlacement, newRelativePlacement);
                        }
                        else
                        {
                            IFCAnyHandle oldOriginHnd, zDirHnd, xDirHnd;
                            xDirHnd      = IFCAnyHandleUtil.GetInstanceAttribute(relativePlacement, "RefDirection");
                            zDirHnd      = IFCAnyHandleUtil.GetInstanceAttribute(relativePlacement, "Axis");
                            oldOriginHnd = IFCAnyHandleUtil.GetInstanceAttribute(relativePlacement, "Location");

                            bool trfSet = false;
                            XYZ  xDir = XYZ.BasisX; XYZ zDir = XYZ.BasisZ; XYZ oldCoords = XYZ.Zero;
                            if (!IFCAnyHandleUtil.IsNullOrHasNoValue(xDirHnd))
                            {
                                xDir   = GeometryUtil.GetDirectionRatios(xDirHnd);
                                trfSet = true;
                            }
                            if (!IFCAnyHandleUtil.IsNullOrHasNoValue(zDirHnd))
                            {
                                zDir   = GeometryUtil.GetDirectionRatios(zDirHnd);
                                trfSet = true;
                            }
                            if (!IFCAnyHandleUtil.IsNullOrHasNoValue(oldOriginHnd))
                            {
                                oldCoords = GeometryUtil.GetCoordinates(oldOriginHnd);
                            }

                            if (trfSet)
                            {
                                XYZ       yDir            = zDir.CrossProduct(xDir);
                                Transform relPlacementTrf = Transform.Identity;
                                relPlacementTrf.Origin = oldCoords; relPlacementTrf.BasisX = xDir;
                                relPlacementTrf.BasisY = yDir; relPlacementTrf.BasisZ = zDir;
                                lpOrig = relPlacementTrf.OfPoint(lpOrig);
                            }
                            else
                            {
                                lpOrig = oldCoords + lpOrig;
                            }

                            IFCAnyHandle newOriginHnd = ExporterUtil.CreateCartesianPoint(file, lpOrig);
                            IFCAnyHandleUtil.SetAttribute(relativePlacement, "Location", newOriginHnd);
                        }
                    }

                    trf.Origin = lpOrig;
                }
                else if (ecData.ForceOffset)
                {
                    ecData.SetLocalPlacement(ExporterUtil.CreateLocalPlacement(file, localPlacement, null));
                }
                else if (!ecData.ReuseLocalPlacement)
                {
                    ecData.SetLocalPlacement(ExporterUtil.CopyLocalPlacement(file, localPlacement));
                }
            }
            return(trf);
        }