Exemple #1
0
        /// <summary>
        /// Create a centerbased cylinder, only on X, Y, Z three axes forward direction
        /// </summary>
        /// <param name="center">The given cylinder center</param>
        /// <param name="bottomradius">The given cylinder's bottom radius</param>
        /// <param name="height">The given cylinder's height</param>
        /// <param name="cylinderdirection">Cylinder's extrusion direction</param>
        /// <returns>The created cylinder</returns>
        public Solid CreateCenterbasedCylinder(XYZ center, double bottomradius, double height, CylinderDirection cylinderdirection)
        {
            double halfheight   = height / 2.0;
            XYZ    bottomcenter = new XYZ(
                cylinderdirection == CylinderDirection.BasisX ? center.X - halfheight : center.X,
                cylinderdirection == CylinderDirection.BasisY ? center.Y - halfheight : center.Y,
                cylinderdirection == CylinderDirection.BasisZ ? center.Z - halfheight : center.Z);
            XYZ topcenter = new XYZ(
                cylinderdirection == CylinderDirection.BasisX ? center.X + halfheight : center.X,
                cylinderdirection == CylinderDirection.BasisY ? center.Y + halfheight : center.Y,
                cylinderdirection == CylinderDirection.BasisZ ? center.Z + halfheight : center.Z);

            CurveLoop sweepPath = new CurveLoop();

            sweepPath.Append(Line.CreateBound(bottomcenter,
                                              topcenter));

            List <CurveLoop> profileloops = new List <CurveLoop>();
            CurveLoop        profileloop  = new CurveLoop();
            Ellipse          cemiEllipse1 = Ellipse.Create(bottomcenter, bottomradius, bottomradius,
                                                           cylinderdirection == CylinderDirection.BasisX ? Autodesk.Revit.DB.XYZ.BasisY : Autodesk.Revit.DB.XYZ.BasisX,
                                                           cylinderdirection == CylinderDirection.BasisZ ? Autodesk.Revit.DB.XYZ.BasisY : Autodesk.Revit.DB.XYZ.BasisZ,
                                                           -Math.PI, 0);
            Ellipse cemiEllipse2 = Ellipse.Create(bottomcenter, bottomradius, bottomradius,
                                                  cylinderdirection == CylinderDirection.BasisX ? Autodesk.Revit.DB.XYZ.BasisY : Autodesk.Revit.DB.XYZ.BasisX,
                                                  cylinderdirection == CylinderDirection.BasisZ ? Autodesk.Revit.DB.XYZ.BasisY : Autodesk.Revit.DB.XYZ.BasisZ,
                                                  0, Math.PI);

            profileloop.Append(cemiEllipse1);
            profileloop.Append(cemiEllipse2);
            profileloops.Add(profileloop);

            return(GeometryCreationUtilities.CreateSweptGeometry(sweepPath, 0, 0, profileloops));
        }
        /// <summary>
        /// Return geometry for a particular representation item.
        /// </summary>
        /// <param name="shapeEditScope">The geometry creation scope.</param>
        /// <param name="unscaledLcs">Local coordinate system for the geometry, without scale.</param>
        /// <param name="scaledLcs">Local coordinate system for the geometry, including scale, potentially non-uniform.</param>
        /// <param name="guid">The guid of an element for which represntation is being created.</param>
        /// <returns>Zero or more created geometries.</returns>
        protected override IList <GeometryObject> CreateGeometryInternal(
            IFCImportShapeEditScope shapeEditScope, Transform unscaledLcs, Transform scaledLcs, string guid)
        {
            Transform unscaledSweptDiskPosition = (unscaledLcs == null) ? Transform.Identity : unscaledLcs;
            Transform scaledSweptDiskPosition   = (scaledLcs == null) ? Transform.Identity : scaledLcs;

            CurveLoop trimmedDirectrix = IFCGeometryUtil.TrimCurveLoop(Id, Directrix, StartParameter, EndParameter);

            if (trimmedDirectrix == null)
            {
                return(null);
            }

            CurveLoop trimmedDirectrixInWCS = IFCGeometryUtil.CreateTransformed(trimmedDirectrix, Id, unscaledSweptDiskPosition, scaledSweptDiskPosition);

            // Create the disk.
            Curve firstCurve = null;

            foreach (Curve curve in trimmedDirectrixInWCS)
            {
                firstCurve = curve;
                break;
            }

            double            startParam        = 0.0;
            IList <CurveLoop> profileCurveLoops = CreateProfileCurveLoopsForDirectrix(firstCurve, out startParam);

            if (profileCurveLoops == null)
            {
                return(null);
            }

            SolidOptions           solidOptions = new SolidOptions(GetMaterialElementId(shapeEditScope), shapeEditScope.GraphicsStyleId);
            IList <GeometryObject> myObjs       = new List <GeometryObject>();

            try
            {
                Solid sweptDiskSolid = GeometryCreationUtilities.CreateSweptGeometry(trimmedDirectrixInWCS, 0, startParam, profileCurveLoops,
                                                                                     solidOptions);
                if (sweptDiskSolid != null)
                {
                    myObjs.Add(sweptDiskSolid);
                }
            }
            catch (Exception ex)
            {
                // If we can't create a solid, we will attempt to split the Solid into valid pieces (that will likely have some overlap).
                if (ex.Message.Contains("self-intersections"))
                {
                    Importer.TheLog.LogWarning(Id, "The IfcSweptDiskSolid definition does not define a valid solid, likely due to self-intersections or other such problems; the profile probably extends too far toward the inner curvature of the sweep path. Creating the minimum number of solids possible to represent the geometry.", false);
                    myObjs = SplitSweptDiskIntoValidPieces(trimmedDirectrixInWCS, profileCurveLoops, solidOptions);
                }
                else
                {
                    throw ex;
                }
            }

            return(myObjs);
        }
Exemple #3
0
        protected List <GeometryObject> CreateConformalGeometryIfPossible(
            IFCImportShapeEditScope shapeEditScope, Transform unscaledLcs)
        {
            Transform unscaledSweptDiskPosition = (unscaledLcs == null) ? Transform.Identity : unscaledLcs;

            IList <CurveLoop> trimmedDirectrices = IFCGeometryUtil.TrimCurveLoops(Id, Directrix, StartParameter, EndParameter);

            if (trimmedDirectrices == null)
            {
                return(null);
            }

            List <GeometryObject> myObjs = null;
            bool isIdentity = unscaledSweptDiskPosition.IsIdentity;

            foreach (CurveLoop trimmedDirectrix in trimmedDirectrices)
            {
                // Create the disk.
                Curve firstCurve = null;
                foreach (Curve curve in trimmedDirectrix)
                {
                    firstCurve = curve;
                    break;
                }

                double            startParam        = 0.0;
                IList <CurveLoop> profileCurveLoops = CreateProfileCurveLoopsForDirectrix(firstCurve, out startParam);
                if (profileCurveLoops == null)
                {
                    return(null);
                }

                SolidOptions solidOptions = new SolidOptions(GetMaterialElementId(shapeEditScope), shapeEditScope.GraphicsStyleId);
                myObjs = new List <GeometryObject>();

                try
                {
                    Solid sweptDiskSolid = GeometryCreationUtilities.CreateSweptGeometry(trimmedDirectrix, 0, startParam, profileCurveLoops,
                                                                                         solidOptions);
                    if (!isIdentity)
                    {
                        sweptDiskSolid = SolidUtils.CreateTransformed(sweptDiskSolid, unscaledSweptDiskPosition);
                    }

                    if (sweptDiskSolid != null)
                    {
                        myObjs.Add(sweptDiskSolid);
                    }
                }
                catch
                {
                    return(null);
                }
            }

            return(myObjs);
        }
Exemple #4
0
        /// <summary>
        /// creates a DirectShape instance of which shape is Plane.
        /// Plane is defined by four vertices (top-left, top-right, bottom-left, bottom-right) on the plane.
        /// (Actually, it is a rectangle as you already know.)
        /// </summary>
        /// <remarks>The Plane has very small thickness (0.0039) since there is no way to create a plane with no thickness using DirectShape.</remarks>
        /// <param name="document">The Revit document where the instance to be drawn</param>
        /// <param name="name">The name of this instance</param>
        /// <param name="top_left">Position of the top-left vertex</param>
        /// <param name="top_right">Position of the top-right vertex</param>
        /// <param name="bottom_left">Position of the bottom-left vertex</param>
        /// <param name="bottom_right">Position of the bottom-right vertex</param>
        /// <param name="line_color">Outline color of Plane</param>
        /// <param name="surface_transparency">Surface transparency; ranged from 0 (transparent) to 100 (opaque)</param>
        public DirectPlane(Document document, string name, XYZ top_left, XYZ top_right, XYZ bottom_left, XYZ bottom_right, Color line_color, int surface_transparency) : base(document, name)
        {
            m_shape_type = ShapeTypes.Plane;
            TopLeft      = top_left;
            TopRight     = top_right;
            BottomLeft   = bottom_left;
            BottomRight  = bottom_right;

            XYZ    rotation_axis, translation_offset;
            double rotation_angle;
            XYZ    tl, tr;
            XYZ    bl, br;

            // We'll rotates and translates the plane transformed to be axis-aligned, because GeometryCreationUtilities.CreateSweptGeometry may fail to define a plane due to the precision issue.
            GetAxisAlignedPlane(
                top_left, top_right, bottom_left, bottom_right,
                out tl, out tr, out bl, out br,
                out rotation_axis, out rotation_angle, out translation_offset);

            Frame frame = new Frame(XYZ.Zero, XYZ.BasisX, XYZ.BasisY, XYZ.BasisZ);

            List <Curve> profile = new List <Curve>();

            profile.Add(Line.CreateBound(tl, bl));
            profile.Add(Line.CreateBound(bl, br));
            profile.Add(Line.CreateBound(br, tr));
            profile.Add(Line.CreateBound(tr, tl));

            List <Curve> swept_profile = new List <Curve>();

            swept_profile.Add(Line.CreateBound(XYZ.Zero, 0.0039 * XYZ.BasisZ));

            CurveLoop    curve_loop = CurveLoop.Create(profile);
            CurveLoop    sweep_path = CurveLoop.Create(swept_profile);
            SolidOptions options    = new SolidOptions(ElementId.InvalidElementId, ElementId.InvalidElementId);

            if (Frame.CanDefineRevitGeometry(frame) == true)
            {
                Solid thin_box = GeometryCreationUtilities.CreateSweptGeometry(sweep_path, 0, 0, new CurveLoop[] { curve_loop }, options);
                using (Transaction t = new Transaction(document, "Create plane direct shape"))
                {
                    t.Start();
                    DirectShape shape = DirectShape.CreateElement(document, new ElementId(BuiltInCategory.OST_GenericModel));
                    shape.SetShape(new GeometryObject[] { thin_box });
                    shape.SetName(name);
                    m_element_id = shape.Id;
                    shape.Location.Rotate(Line.CreateUnbound(XYZ.Zero, rotation_axis), -rotation_angle);
                    shape.Location.Move(-translation_offset);
                    document.ActiveView.SetElementOverrides(shape.Id, new OverrideGraphicSettings().SetProjectionLineColor(line_color).SetSurfaceTransparency(surface_transparency));
                    t.Commit();
                }
            }
        }
        public static Solid CreateCylindricalSolidFromCurve(this Curve curve, double radius = 0.1)
        {
            var       trans   = curve.ComputeDerivatives(0, true);
            Plane     plane   = Plane.CreateByNormalAndOrigin(trans.BasisX.Normalize(), curve.GetEndPoint(0));
            CurveLoop profile = CurveLoop.Create(new[] {
                Arc.Create(plane, radius, 0, Math.PI),
                Arc.Create(plane, radius, Math.PI, 2 * Math.PI)
            });
            var path = CurveLoop.Create(new[] { curve });

            return(GeometryCreationUtilities.CreateSweptGeometry(path, 0, curve.GetEndParameter(0), new[] { profile }));
        }
Exemple #6
0
        /// <summary>
        /// creates a DirectShape instance of which shape is Cylinder.
        /// Cylinder is defined by two circles (top, bottom) with the same radius.
        /// </summary>
        /// <param name="document">The Revit document where the instance to be drawn</param>
        /// <param name="name">The name of this instance</param>
        /// <param name="doc">The Revit document where the instance to be drawn</param>
        /// <param name="top">Position of center of the top circle</param>
        /// <param name="bottom">Position of center of the bottom circle</param>
        /// <param name="radius">Radius of the circles</param>
        /// <param name="line_color">Outline color of Cylinder</param>
        /// <param name="surface_transparency">Surface transparency; ranged from 0 (transparent) to 100 (opaque)</param>
        public DirectCylinder(Document document, string name, XYZ top, XYZ bottom, double radius, Color line_color, int surface_transparency) : base(document, name)
        {
            m_shape_type = ShapeTypes.Cylinder;
            Top          = top;
            Bottom       = bottom;
            Radius       = radius;

            // defines a reference frame of which origin is at the center of the cylinder and z-axis is passing through the centers of its top and bottom.
            XYZ center  = (top + bottom) / 2;
            XYZ basis_z = (top - bottom).Normalize();
            XYZ basis_x = XYZ.BasisY.CrossProduct(basis_z).Normalize();
            XYZ basis_y = basis_z.CrossProduct(basis_x).Normalize();

            Frame frame = new Frame(center, basis_x, basis_y, basis_z);

            XYZ bottom_left  = bottom - radius * basis_x;
            XYZ bottom_right = bottom + radius * basis_x;
            XYZ bottom_front = bottom - radius * basis_y;
            XYZ bottom_back  = bottom + radius * basis_y;

            // creates a profile that is a cross section of a circle (the cylinder will be made by sweeping through the z-axis).
            List <Curve> profile = new List <Curve>();

            profile.Add(Arc.Create(bottom_left, bottom_right, bottom_back));
            profile.Add(Arc.Create(bottom_right, bottom_left, bottom_front));

            List <Curve> swept_profile = new List <Curve>();

            swept_profile.Add(Line.CreateBound(bottom, top));

            CurveLoop    curve_loop = CurveLoop.Create(profile);
            CurveLoop    sweep_path = CurveLoop.Create(swept_profile);
            SolidOptions options    = new SolidOptions(ElementId.InvalidElementId, ElementId.InvalidElementId);

            if (Frame.CanDefineRevitGeometry(frame) == true)
            {
                Solid cylinder = GeometryCreationUtilities.CreateSweptGeometry(sweep_path, 0, 0, new CurveLoop[] { curve_loop }, options);
                using (Transaction t = new Transaction(document, "Create cylinder direct shape"))
                {
                    t.Start();
                    DirectShape shape = DirectShape.CreateElement(document, new ElementId(BuiltInCategory.OST_GenericModel));
                    shape.SetShape(new GeometryObject[] { cylinder });
                    shape.SetName(name);
                    m_element_id = shape.Id;
                    document.ActiveView.SetElementOverrides(shape.Id, new OverrideGraphicSettings().SetProjectionLineColor(line_color).SetSurfaceTransparency(surface_transparency));
                    t.Commit();
                }
            }
        }
        // Token: 0x060001EF RID: 495 RVA: 0x0000DAD0 File Offset: 0x0000BCD0
        private static Solid GetSolid(List <Curve> centerLineCurve, List <CurveLoop> profile)
        {
            bool  flag = centerLineCurve.none <Curve>();
            Solid result;

            if (flag)
            {
                result = null;
            }
            else
            {
                CurveLoop curveLoop    = CurveLoop.Create(centerLineCurve);
                double    endParameter = centerLineCurve[0].GetEndParameter(0);
                Solid     solid        = GeometryCreationUtilities.CreateSweptGeometry(curveLoop, 0, endParameter, profile);
                result = solid;
            }
            return(result);
        }
        public static void CreateCenterbasedCylinder(Document doc, XYZ center, double bottomradius, double height, CylinderDirection cylinderdirection, String name)
        {
            double halfheight   = height / 2.0;
            XYZ    bottomcenter = new XYZ(
                cylinderdirection == CylinderDirection.BasisX ? center.X - halfheight : center.X,
                cylinderdirection == CylinderDirection.BasisY ? center.Y - halfheight : center.Y,
                cylinderdirection == CylinderDirection.BasisZ ? center.Z - halfheight : center.Z);
            XYZ topcenter = new XYZ(
                cylinderdirection == CylinderDirection.BasisX ? center.X + halfheight : center.X,
                cylinderdirection == CylinderDirection.BasisY ? center.Y + halfheight : center.Y,
                cylinderdirection == CylinderDirection.BasisZ ? center.Z + halfheight : center.Z);

            CurveLoop sweepPath = new CurveLoop();

            sweepPath.Append(Line.CreateBound(bottomcenter,
                                              topcenter));

            List <CurveLoop> profileloops = new List <CurveLoop>();
            CurveLoop        profileloop  = new CurveLoop();
            Ellipse          cemiEllipse1 = Ellipse.Create(bottomcenter, bottomradius, bottomradius,
                                                           cylinderdirection == CylinderDirection.BasisX ? Autodesk.Revit.DB.XYZ.BasisY : Autodesk.Revit.DB.XYZ.BasisX,
                                                           cylinderdirection == CylinderDirection.BasisZ ? Autodesk.Revit.DB.XYZ.BasisY : Autodesk.Revit.DB.XYZ.BasisZ,
                                                           -Math.PI, 0);
            Ellipse cemiEllipse2 = Ellipse.Create(bottomcenter, bottomradius, bottomradius,
                                                  cylinderdirection == CylinderDirection.BasisX ? Autodesk.Revit.DB.XYZ.BasisY : Autodesk.Revit.DB.XYZ.BasisX,
                                                  cylinderdirection == CylinderDirection.BasisZ ? Autodesk.Revit.DB.XYZ.BasisY : Autodesk.Revit.DB.XYZ.BasisZ,
                                                  0, Math.PI);

            profileloop.Append(cemiEllipse1);
            profileloop.Append(cemiEllipse2);
            profileloops.Add(profileloop);
            Solid cyl = GeometryCreationUtilities.CreateSweptGeometry(sweepPath, 0, 0, profileloops);

            using (Transaction t = new Transaction(doc, "Create cylinder direct shape"))
            {
                t.Start();
                DirectShape ds = DirectShape.CreateElement(doc, new ElementId(BuiltInCategory.OST_GenericModel));
                ds.SetShape(new GeometryObject[] { cyl });
                ds.Name = name;
                t.Commit();
            }
        }
Exemple #9
0
        public override Value Evaluate(FSharpList <Value> args)
        {
            //unwrap the values
            IEnumerable <double> nvals = ((Value.List)args[0]).Item.Select(q => (double)((Value.Number)q).Item);

            var curve = (Curve)((Value.Container)args[1]).Item;

            sfm = (SpatialFieldManager)((Value.Container)args[2]).Item;

            if (!sfm.IsResultSchemaNameUnique(DYNAMO_TEMP_CURVES_SCHEMA, -1))
            {
                IList <int> arses = sfm.GetRegisteredResults();
                foreach (int i in arses)
                {
                    AnalysisResultSchema arsTest = sfm.GetResultSchema(i);
                    if (arsTest.Name == DYNAMO_TEMP_CURVES_SCHEMA)
                    {
                        schemaId = i;
                        break;
                    }
                }
            }
            else
            {
                var ars = new AnalysisResultSchema(DYNAMO_TEMP_CURVES_SCHEMA, "Temporary curves from Dynamo.");
                schemaId = sfm.RegisterResult(ars);
            }

            Transform trf = Transform.Identity;

            //http://thebuildingcoder.typepad.com/blog/2012/09/sphere-creation-for-avf-and-filtering.html#3

            var create = dynRevitSettings.Doc.Application.Application.Create;

            Transform t = curve.ComputeDerivatives(0, true);

            XYZ x = t.BasisX.Normalize();
            XYZ y = t.BasisX.IsAlmostEqualTo(XYZ.BasisZ) ?
                    t.BasisX.CrossProduct(XYZ.BasisY).Normalize() :
                    t.BasisX.CrossProduct(XYZ.BasisZ).Normalize();
            XYZ z = x.CrossProduct(y);

            Ellipse arc1 = dynRevitSettings.Revit.Application.Create.NewEllipse(t.Origin, .1, .1, y, z, -Math.PI, 0);
            Ellipse arc2 = dynRevitSettings.Revit.Application.Create.NewEllipse(t.Origin, .1, .1, y, z, 0, Math.PI);

            var pathLoop = new CurveLoop();

            pathLoop.Append(curve);
            var profileLoop = new CurveLoop();

            profileLoop.Append(arc1);
            profileLoop.Append(arc2);

            double curveDomain = curve.get_EndParameter(1) - curve.get_EndParameter(0);

            int idx = -1;
            var s   = GeometryCreationUtilities.CreateSweptGeometry(pathLoop, 0, 0, new List <CurveLoop> {
                profileLoop
            });

            foreach (Face face in s.Faces)
            {
                //divide the V domain by the number of incoming
                BoundingBoxUV domain = face.GetBoundingBox();
                double        vSpan  = domain.Max.V - domain.Min.V;

                //analysis values
                idx = sfm.AddSpatialFieldPrimitive(face, trf);

                //a list to hold the analysis points
                IList <UV> uvPts = new List <UV>();

                //a list to hold the analysis values
                IList <ValueAtPoint> valList = new List <ValueAtPoint>();

                //int count = nvals.Count();

                //this is creating a lot of sample points, but if we used less
                //sampling points, AVF would draw the two surfaces as if there was a hard
                //edge between them. this provides a better blend.
                int count = 10;
                for (int i = 0; i < count; i++)
                {
                    //get a UV point on the face
                    //find its XYZ location and project to
                    //the underlying curve. find the value which corresponds
                    //to the location on the curve
                    var uv  = new UV(domain.Min.U, domain.Min.V + vSpan / count * (double)i);
                    var uv1 = new UV(domain.Max.U, domain.Min.V + vSpan / count * (double)i);
                    uvPts.Add(uv);
                    uvPts.Add(uv1);

                    XYZ facePt                    = face.Evaluate(uv);
                    IntersectionResult ir         = curve.Project(facePt);
                    double             curveParam = curve.ComputeNormalizedParameter(ir.Parameter);

                    if (curveParam < 0)
                    {
                        curveParam = 0;
                    }

                    if (curveParam > 1)
                    {
                        curveParam = 1;
                    }

                    var valueIndex = (int)Math.Floor(curveParam * (double)nvals.Count());
                    if (valueIndex >= nvals.Count())
                    {
                        valueIndex = nvals.Count() - 1;
                    }

                    //create list of values at this point - currently supporting only one
                    //var doubleList = new List<double> { nvals.ElementAt(i) };
                    var doubleList = new List <double> {
                        nvals.ElementAt(valueIndex)
                    };

                    //add value at point object containing the value list
                    valList.Add(new ValueAtPoint(doubleList));
                    valList.Add(new ValueAtPoint(doubleList));
                }

                var pnts = new FieldDomainPointsByUV(uvPts);
                var vals = new FieldValues(valList);

                sfm.UpdateSpatialFieldPrimitive(
                    idx, pnts, vals, schemaId);

                idxs.Add(idx);
            }

            return(Value.NewNumber(idx));
        }
        /// <summary>
        /// Return geometry for a particular representation item.
        /// </summary>
        /// <param name="shapeEditScope">The geometry creation scope.</param>
        /// <param name="unscaledLcs">The unscaled local coordinate system for the geometry, if the scaled version isn't supported downstream.</param>
        /// <param name="scaledLcs">The scaled (true) local coordinate system for the geometry.</param>
        /// <param name="guid">The guid of an element for which represntation is being created.</param>
        /// <returns>The created geometry.</returns>
        protected override IList <GeometryObject> CreateGeometryInternal(
            IFCImportShapeEditScope shapeEditScope, Transform unscaledLcs, Transform scaledLcs, string guid)
        {
            Transform unscaledObjectPosition = (unscaledLcs == null) ? Position : unscaledLcs.Multiply(Position);
            Transform scaledObjectPosition   = (scaledLcs == null) ? Position : scaledLcs.Multiply(Position);

            CurveLoop baseProfileCurve = Directrix.GetCurveLoop();

            if (baseProfileCurve == null)
            {
                return(null);
            }

            CurveLoop trimmedDirectrix = IFCGeometryUtil.TrimCurveLoop(Id, baseProfileCurve, StartParameter, EndParameter);

            if (trimmedDirectrix == null)
            {
                return(null);
            }

            double    startParam  = 0.0; // If the directrix isn't bound, this arbitrary parameter will do.
            Transform originTrf0  = null;
            Curve     firstCurve0 = trimmedDirectrix.First();

            if (firstCurve0.IsBound)
            {
                startParam = firstCurve0.GetEndParameter(0);
            }
            originTrf0 = firstCurve0.ComputeDerivatives(startParam, false);
            if (originTrf0 == null)
            {
                return(null);
            }

            // Note: the computation of the reference Surface Local Transform must be done before the directrix is transform to LCS (because the ref surface isn't)
            //     and therefore the origin is at the start of the curve should be the start of the directrix that lies on the surface.
            //     This is needed to transform the swept area that must be perpendicular to the start of the directrix curve

            Transform referenceSurfaceLocalTransform = ReferenceSurface.GetTransformAtPoint(originTrf0.Origin);

            CurveLoop trimmedDirectrixInLCS = IFCGeometryUtil.CreateTransformed(trimmedDirectrix, Id, unscaledObjectPosition, scaledObjectPosition);

            // Create the sweep.
            Transform originTrf  = null;
            Curve     firstCurve = trimmedDirectrixInLCS.First();

            //if (firstCurve.IsBound)
            //    startParam = firstCurve.GetEndParameter(0);
            originTrf = firstCurve.ComputeDerivatives(startParam, false);

            Transform unscaledReferenceSurfaceTransform = unscaledObjectPosition.Multiply(referenceSurfaceLocalTransform);
            Transform scaledReferenceSurfaceTransform   = scaledObjectPosition.Multiply(referenceSurfaceLocalTransform);

            Transform profileCurveLoopsTransform = Transform.CreateTranslation(originTrf.Origin);

            profileCurveLoopsTransform.BasisX = scaledReferenceSurfaceTransform.BasisZ;
            profileCurveLoopsTransform.BasisZ = originTrf.BasisX.Normalize();
            profileCurveLoopsTransform.BasisY = profileCurveLoopsTransform.BasisZ.CrossProduct(profileCurveLoopsTransform.BasisX);

            ISet <IList <CurveLoop> > profileCurveLoops = GetTransformedCurveLoops(profileCurveLoopsTransform, profileCurveLoopsTransform);

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

            SolidOptions           solidOptions = new SolidOptions(GetMaterialElementId(shapeEditScope), shapeEditScope.GraphicsStyleId);
            IList <GeometryObject> myObjs       = new List <GeometryObject>();

            foreach (IList <CurveLoop> loops in profileCurveLoops)
            {
                GeometryObject myObj = GeometryCreationUtilities.CreateSweptGeometry(trimmedDirectrixInLCS, 0, startParam, loops, solidOptions);
                if (myObj != null)
                {
                    myObjs.Add(myObj);
                }
            }

            return(myObjs);
        }
Exemple #11
0
        /// <summary>
        /// Return geometry for a particular representation item.
        /// </summary>
        /// <param name="shapeEditScope">The geometry creation scope.</param>
        /// <param name="lcs">Local coordinate system for the geometry, without scale.</param>
        /// <param name="scaledLcs">Local coordinate system for the geometry, including scale, potentially non-uniform.</param>
        /// <param name="guid">The guid of an element for which represntation is being created.</param>
        /// <returns>Zero or more created geometries.</returns>
        protected override IList <GeometryObject> CreateGeometryInternal(
            IFCImportShapeEditScope shapeEditScope, Transform lcs, Transform scaledLcs, string guid)
        {
            Transform sweptDiskPosition = (lcs == null) ? Transform.Identity : lcs;

            CurveLoop baseProfileCurve = Directrix.GetCurveLoop();

            if (baseProfileCurve == null)
            {
                return(null);
            }

            CurveLoop trimmedDirectrix = IFCGeometryUtil.TrimCurveLoop(baseProfileCurve, StartParameter, EndParameter);

            if (trimmedDirectrix == null)
            {
                return(null);
            }

            CurveLoop trimmedDirectrixInLCS = IFCGeometryUtil.CreateTransformed(trimmedDirectrix, sweptDiskPosition);

            // Create the disk.
            Transform originTrf  = null;
            double    startParam = 0.0; // If the directrix isn't bound, this arbitrary parameter will do.

            foreach (Curve curve in trimmedDirectrixInLCS)
            {
                if (curve.IsBound)
                {
                    startParam = curve.GetEndParameter(0);
                }
                originTrf = curve.ComputeDerivatives(startParam, false);
                break;
            }

            if (originTrf == null)
            {
                return(null);
            }

            // The X-dir of the transform of the start of the directrix will form the normal of the disk.
            Plane diskPlane = new Plane(originTrf.BasisX, originTrf.Origin);

            IList <CurveLoop> profileCurveLoops = new List <CurveLoop>();

            CurveLoop diskOuterCurveLoop = new CurveLoop();

            diskOuterCurveLoop.Append(Arc.Create(diskPlane, Radius, 0, Math.PI));
            diskOuterCurveLoop.Append(Arc.Create(diskPlane, Radius, Math.PI, 2.0 * Math.PI));
            profileCurveLoops.Add(diskOuterCurveLoop);

            if (InnerRadius.HasValue)
            {
                CurveLoop diskInnerCurveLoop = new CurveLoop();
                diskInnerCurveLoop.Append(Arc.Create(diskPlane, InnerRadius.Value, 0, Math.PI));
                diskInnerCurveLoop.Append(Arc.Create(diskPlane, InnerRadius.Value, Math.PI, 2.0 * Math.PI));
                profileCurveLoops.Add(diskInnerCurveLoop);
            }

            SolidOptions solidOptions   = new SolidOptions(GetMaterialElementId(shapeEditScope), shapeEditScope.GraphicsStyleId);
            Solid        sweptDiskSolid = GeometryCreationUtilities.CreateSweptGeometry(trimmedDirectrixInLCS, 0, startParam, profileCurveLoops,
                                                                                        solidOptions);

            IList <GeometryObject> myObjs = new List <GeometryObject>();

            if (sweptDiskSolid != null)
            {
                myObjs.Add(sweptDiskSolid);
            }
            return(myObjs);
        }
Exemple #12
0
        /// <summary>
        /// Return geometry for a particular representation item.
        /// </summary>
        /// <param name="shapeEditScope">The geometry creation scope.</param>
        /// <param name="lcs">Local coordinate system for the geometry.</param>
        /// <param name="guid">The guid of an element for which represntation is being created.</param>
        /// <returns>The created geometry.</returns>
        protected override IList <GeometryObject> CreateGeometryInternal(
            IFCImportShapeEditScope shapeEditScope, Transform lcs, Transform scaledLcs, string guid)
        {
            Transform objectPosition = (lcs == null) ? Position : lcs.Multiply(Position);

            CurveLoop baseProfileCurve = Directrix.GetCurveLoop();

            if (baseProfileCurve == null)
            {
                return(null);
            }

            CurveLoop trimmedDirectrix = IFCGeometryUtil.TrimCurveLoop(baseProfileCurve, StartParameter, EndParameter);

            if (trimmedDirectrix == null)
            {
                return(null);
            }

            CurveLoop trimmedDirectrixInLCS = IFCGeometryUtil.CreateTransformed(trimmedDirectrix, objectPosition);

            // Create the sweep.
            double    startParam = 0.0; // If the directrix isn't bound, this arbitrary parameter will do.
            Transform originTrf  = null;
            Curve     firstCurve = trimmedDirectrixInLCS.First();

            if (firstCurve.IsBound)
            {
                startParam = firstCurve.GetEndParameter(0);
            }
            originTrf = firstCurve.ComputeDerivatives(startParam, false);

            if (originTrf == null)
            {
                return(null);
            }

            Transform referenceSurfaceLocalTransform = ReferenceSurface.GetTransformAtPoint(originTrf.Origin);
            Transform referenceSurfaceTransform      = objectPosition.Multiply(referenceSurfaceLocalTransform);

            Transform profileCurveLoopsTransform = Transform.CreateTranslation(originTrf.Origin);

            profileCurveLoopsTransform.BasisX = referenceSurfaceTransform.BasisZ;
            profileCurveLoopsTransform.BasisZ = originTrf.BasisX.Normalize();
            profileCurveLoopsTransform.BasisY = profileCurveLoopsTransform.BasisZ.CrossProduct(profileCurveLoopsTransform.BasisX);

            ISet <IList <CurveLoop> > profileCurveLoops = GetTransformedCurveLoops(profileCurveLoopsTransform);

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

            SolidOptions           solidOptions = new SolidOptions(GetMaterialElementId(shapeEditScope), shapeEditScope.GraphicsStyleId);
            IList <GeometryObject> myObjs       = new List <GeometryObject>();

            foreach (IList <CurveLoop> loops in profileCurveLoops)
            {
                GeometryObject myObj = GeometryCreationUtilities.CreateSweptGeometry(trimmedDirectrixInLCS, 0, startParam, loops, solidOptions);
                if (myObj != null)
                {
                    myObjs.Add(myObj);
                }
            }

            return(myObjs);
        }
        private IList <GeometryObject> SplitSweptDiskIntoValidPieces(CurveLoop trimmedDirectrixInWCS, IList <CurveLoop> profileCurveLoops, SolidOptions solidOptions)
        {
            // If we have 0 or 1 curves, there is nothing we can do here.
            int numCurves = trimmedDirectrixInWCS.Count();

            if (numCurves < 2)
            {
                return(null);
            }

            // We will attempt to represent the original description in as few pieces as possible.
            IList <Curve> directrixCurves = new List <Curve>();

            foreach (Curve directrixCurve in trimmedDirectrixInWCS)
            {
                if (directrixCurve == null)
                {
                    numCurves--;
                    if (numCurves < 2)
                    {
                        return(null);
                    }
                    continue;
                }
                directrixCurves.Add(directrixCurve);
            }

            IList <GeometryObject> sweptDiskPieces = new List <GeometryObject>();

            // We will march along the directrix one curve at a time, trying to build a bigger piece of the sweep.  At the point that we throw an exception,
            // we will take the last biggest piece and start over.
            CurveLoop currentCurveLoop    = new CurveLoop();
            Solid     bestSolidSoFar      = null;
            double    pathAttachmentParam = directrixCurves[0].GetEndParameter(0);

            for (int ii = 0; ii < numCurves; ii++)
            {
                currentCurveLoop.Append(directrixCurves[ii]);
                try
                {
                    Solid currentSolid = GeometryCreationUtilities.CreateSweptGeometry(currentCurveLoop, 0, pathAttachmentParam, profileCurveLoops,
                                                                                       solidOptions);
                    bestSolidSoFar = currentSolid;
                }
                catch
                {
                    if (bestSolidSoFar != null)
                    {
                        sweptDiskPieces.Add(bestSolidSoFar);
                        bestSolidSoFar = null;
                    }
                }

                // This should only happen as a result of the catch loop above.  We want to protect against the case where one or more pieces of the sweep
                // are completely invalid.
                while (bestSolidSoFar == null && (ii < numCurves))
                {
                    try
                    {
                        currentCurveLoop = new CurveLoop();
                        currentCurveLoop.Append(directrixCurves[ii]);
                        profileCurveLoops = CreateProfileCurveLoopsForDirectrix(directrixCurves[ii], out pathAttachmentParam);

                        Solid currentSolid = GeometryCreationUtilities.CreateSweptGeometry(currentCurveLoop, 0, pathAttachmentParam, profileCurveLoops,
                                                                                           solidOptions);
                        bestSolidSoFar = currentSolid;
                        break;
                    }
                    catch
                    {
                        ii++;
                    }
                }
            }

            return(sweptDiskPieces);
        }
Exemple #14
0
 /// <summary>
 /// Create a swept geometry
 /// </summary>
 /// <param name="sweepPath">The sweep path, consisting of a set of contiguous curves</param>
 /// <param name="pathAttachmentCrvIdx">The index of the curve in the sweep path where the profile loops are situated</param>
 /// <param name="pathAttachmentParam">Parameter of the path curve specified by pathAttachmentCrvIdx</param>
 /// <param name="profileLoops">The curve loops defining the planar domain to be swept along the path</param>
 /// <returns>The created solid</returns>
 private Solid CreateSwept(CurveLoop sweepPath, int pathAttachmentCrvIdx, double pathAttachmentParam, List <CurveLoop> profileLoops)
 {
     return(GeometryCreationUtilities.CreateSweptGeometry(sweepPath, pathAttachmentCrvIdx, pathAttachmentParam, profileLoops));
 }
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            Document doc = commandData.Application.ActiveUIDocument.Document;

            Autodesk.Revit.UI.Selection.Selection sel = commandData.Application.ActiveUIDocument.Selection;
            Reference   reference = sel.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element);
            Transaction trans     = new Transaction(doc);
            Element     elem      = doc.GetElement(reference);

            trans.Start("Create solid");
            LocationCurve lc = elem.Location as LocationCurve;

            if (lc == null)
            {
                throw new InvalidOperationException("Current element is not a curve-dirven element");
            }
            //Create the sweep path
            var   pathCurveLoop = new CurveLoop();
            Curve curve         = lc.Curve;

            pathCurveLoop.Append(curve);
            //get the point to create a plane for the profile.
            XYZ xyzFirstPoint = curve.GetEndPoint(0);
            //Create the plane
            Transform transform    = curve.ComputeDerivatives(0, true);
            XYZ       xyzDirection = transform.BasisX;
            Plane     profilePlane = Plane.CreateByNormalAndOrigin(xyzDirection.Normalize(), transform.Origin);
            //Create a profile which is a rectangle with height and width of 2000mm and 900mm

            double    dblHeight = 2000 / 304.8;
            double    dblWidth  = 900 / 304.8;
            UV        uvPt0     = new UV(0, 0) - new UV(dblWidth / 2, 0);
            UV        uvPt1     = uvPt0 + new UV(dblWidth, 0);
            UV        uvPt2     = uvPt1 + new UV(0, dblHeight);
            UV        uvPt3     = uvPt2 - new UV(dblWidth, 0);
            XYZ       xVec      = profilePlane.XVec;
            XYZ       yVec      = profilePlane.YVec;
            XYZ       xyzPt0    = profilePlane.Origin + profilePlane.XVec.Multiply(uvPt0.U) + profilePlane.YVec.Multiply(uvPt0.V);
            XYZ       xyzPt1    = profilePlane.Origin + profilePlane.XVec.Multiply(uvPt1.U) + profilePlane.YVec.Multiply(uvPt1.V);
            XYZ       xyzPt2    = profilePlane.Origin + profilePlane.XVec.Multiply(uvPt2.U) + profilePlane.YVec.Multiply(uvPt2.V);
            XYZ       xyzPt3    = profilePlane.Origin + profilePlane.XVec.Multiply(uvPt3.U) + profilePlane.YVec.Multiply(uvPt3.V);
            Line      l1        = Line.CreateBound(xyzPt0, xyzPt1);
            Line      l2        = Line.CreateBound(xyzPt1, xyzPt2);
            Line      l3        = Line.CreateBound(xyzPt2, xyzPt3);
            Line      l4        = Line.CreateBound(xyzPt3, xyzPt0);
            CurveLoop loop      = new CurveLoop();

            loop.Append(l1);
            loop.Append(l2);
            loop.Append(l3);
            loop.Append(l4);
            List <CurveLoop> newloops = new List <CurveLoop>()
            {
                loop
            };
            //Create the swept solid
            Solid sweepSolid = GeometryCreationUtilities.CreateSweptGeometry(pathCurveLoop, 0, lc.Curve.GetEndParameter(0), newloops);
            //Create a directShape to visualize the solid
            DirectShape ds = DirectShape.CreateElement(doc, new ElementId(BuiltInCategory.OST_GenericModel));

            ds.AppendShape(new Solid[1] {
                sweepSolid
            });
            trans.Commit();
            return(Result.Succeeded);
        }
Exemple #16
0
        /// <summary>
        /// Return geometry for a particular representation item.
        /// </summary>
        /// <param name="shapeEditScope">The geometry creation scope.</param>
        /// <param name="unscaledLcs">Local coordinate system for the geometry, without scale.</param>
        /// <param name="scaledLcs">Local coordinate system for the geometry, including scale, potentially non-uniform.</param>
        /// <param name="guid">The guid of an element for which represntation is being created.</param>
        /// <returns>Zero or more created geometries.</returns>
        protected override IList <GeometryObject> CreateGeometryInternal(
            IFCImportShapeEditScope shapeEditScope, Transform unscaledLcs, Transform scaledLcs, string guid)
        {
            List <GeometryObject> myObjs = null;

            if (scaledLcs == null || scaledLcs.IsConformal && MathUtil.IsAlmostEqual(scaledLcs.Scale, 1.0))
            {
                myObjs = CreateConformalGeometryIfPossible(shapeEditScope, unscaledLcs);
                if (myObjs != null)
                {
                    return(myObjs);
                }
            }

            Transform unscaledSweptDiskPosition = (unscaledLcs == null) ? Transform.Identity : unscaledLcs;
            Transform scaledSweptDiskPosition   = (scaledLcs == null) ? Transform.Identity : scaledLcs;

            IList <CurveLoop> trimmedDirectrices = IFCGeometryUtil.TrimCurveLoops(Id, Directrix, StartParameter, EndParameter);

            if (trimmedDirectrices == null)
            {
                return(null);
            }

            foreach (CurveLoop trimmedDirectrix in trimmedDirectrices)
            {
                CurveLoop trimmedDirectrixInWCS = IFCGeometryUtil.CreateTransformed(trimmedDirectrix, Id, unscaledSweptDiskPosition, scaledSweptDiskPosition);

                // Create the disk.
                Curve firstCurve = null;
                foreach (Curve curve in trimmedDirectrixInWCS)
                {
                    firstCurve = curve;
                    break;
                }

                double            startParam        = 0.0;
                IList <CurveLoop> profileCurveLoops = CreateProfileCurveLoopsForDirectrix(firstCurve, out startParam);
                if (profileCurveLoops == null)
                {
                    return(null);
                }

                SolidOptions solidOptions = new SolidOptions(GetMaterialElementId(shapeEditScope), shapeEditScope.GraphicsStyleId);
                myObjs = new List <GeometryObject>();

                try
                {
                    Solid sweptDiskSolid = GeometryCreationUtilities.CreateSweptGeometry(trimmedDirectrixInWCS, 0, startParam, profileCurveLoops,
                                                                                         solidOptions);
                    if (sweptDiskSolid != null)
                    {
                        myObjs.Add(sweptDiskSolid);
                    }
                }
                catch (Exception ex)
                {
                    // If we can't create a solid, we will attempt to split the Solid into valid pieces (that will likely have some overlap).
                    if (ex.Message.Contains("self-intersections") || ex.Message.Contains("Failed to create"))
                    {
                        (IList <GeometryObject>, bool)solidSegments = SplitSweptDiskIntoValidPieces(trimmedDirectrixInWCS, profileCurveLoops, solidOptions);
                        if (solidSegments.Item1 != null)
                        {
                            myObjs.AddRange(solidSegments.Item1);
                        }

                        // If Item2 is true, that means that the backup SplitSweptDiskIntoValidPieces routine was
                        // able to create (probably slightly self-intersecting) geometry for all of the pieces
                        // of the directrix.  If it is false, then there was some part of the directrix that we
                        // couldn't create geometry for.  Log a warning in the first case and an error in the
                        // second.
                        if (solidSegments.Item2)
                        {
                            Importer.TheLog.LogWarning(Id, "The IfcSweptDiskSolid definition does not define a valid solid, likely due to self-intersections or other such problems; the profile probably extends too far toward the inner curvature of the sweep path. Creating the minimum number of solids possible to represent the geometry.", false);
                        }
                        else
                        {
                            Importer.TheLog.LogError(Id, "The IfcSweptDiskSolid definition does not define a valid solid, likely due to self-intersections or other such problems; the profile probably extends too far toward the inner curvature of the sweep path. Creating as much of the geometry as possible.", false);
                        }
                    }
                    else
                    {
                        throw ex;
                    }
                }
            }

            return(myObjs);
        }