public static DirectShape CreateDirectShape(
            Document doc,
            Solid transientSolid,
            string dsName)
        {
            ElementId catId = new ElementId(
                BuiltInCategory.OST_GenericModel);

            AddInId addInId = doc.Application.ActiveAddInId;

            DirectShape ds
                = DirectShape.CreateElement(doc, catId,
                                            addInId.GetGUID().ToString(), "");

            if (ds.IsValidGeometry(transientSolid))
            {
                ds.SetShape(new GeometryObject[] {
                    transientSolid
                });
            }
            else
            {
                TessellatedShapeBuilderResult result
                    = GetTessellatedSolid(doc, transientSolid);

                ds.SetShape(result.GetGeometricalObjects());
            }

            ds.Name = dsName;

            return(ds);
        }
        /// <summary>
        /// Create a geometry object(s) described by stored face sets, if possible.
        /// Usually a single-element IList conatining either Solid or Mesh is returned.
        /// A two-elemant IList containing a Solid as the 1st element and a Mesh as
        /// the 2nd is returned if while building multiple face sets, a fallback
        /// was used for some but not all sets.
        /// </summary>
        /// <returns>The IList created, or null. The IList can contain a Solid and/or a Mesh.
        /// If Solid is present, it always the 1st element.</returns>
        private IList <GeometryObject> CreateGeometryObjects(string guid,
                                                             out bool hasInvalidData, out TessellatedShapeBuilderOutcome outcome)
        {
            try
            {
                m_TessellatedShapeBuilder.CloseConnectedFaceSet();

                // The OwnerInfo is currently unused; the value doesn't really matter.
                m_TessellatedShapeBuilder.LogString  = IFCImportFile.TheFileName;
                m_TessellatedShapeBuilder.LogInteger = IFCImportFile.TheBrepCounter;
                m_TessellatedShapeBuilder.OwnerInfo  = guid != null ? guid : "Temporary Element";

                TessellatedShapeBuilderResult result = m_TessellatedShapeBuilder.Build(TargetGeometry, FallbackGeometry, GraphicsStyleId);

                // It is important that we clear the TSB after we build above, otherwise we will "collect" geometries
                // in the DirectShape and create huge files with redundant data.
                ClearTessellatedShapeBuilder();
                hasInvalidData = result.HasInvalidData;
                outcome        = result.Outcome;
                return(result.GetGeometricalObjects());
            }
            catch (Exception ex)
            {
                Importer.TheLog.LogError(CreatorId(), ex.Message, false);

                ClearTessellatedShapeBuilder();
                hasInvalidData = true;
                outcome        = TessellatedShapeBuilderOutcome.Nothing;
                return(null);
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Creates a solid from a list of points. Intented to create single face solids for solid operations.
        /// </summary>
        /// <param name="vertices">A list of XYZ vertices of the face.</param>
        /// <returns>A solid consisting of one face.</returns>
        public static Solid CreateSolid(IList <XYZ> vertices)
        {
            TessellatedShapeBuilder builder = new TessellatedShapeBuilder();

            //http://thebuildingcoder.typepad.com/blog/2014/05/directshape-performance-and-minimum-size.html
            builder.OpenConnectedFaceSet(false);
            builder.AddFace(new TessellatedFace(vertices, ElementId.InvalidElementId));
            builder.CloseConnectedFaceSet();
            builder.Build();
            TessellatedShapeBuilderResult result = builder.GetBuildResult();

            return(result.GetGeometricalObjects()[0] as Solid);
        }
Ejemplo n.º 4
0
        private void ImportSTLDocument(
            STLDocument stlDocument,
            Document doc,
            string stlDocumentName)
        {
            StlImportProperties properties = StlImportProperties.GetProperties();

            using (Transaction t = new Transaction(doc, "Import STL"))
            {
                t.Start();

                TessellatedShapeBuilder builder = new TessellatedShapeBuilder();

                builder.OpenConnectedFaceSet(false);
                int i = 0;

                foreach (Facet facet in stlDocument.Facets)
                {
                    builder.AddFace(FromFacet(facet));
                    i++;
                }

                builder.CloseConnectedFaceSet();

                TessellatedShapeBuilderResult result
                    = builder.Build(properties.Target,
                                    properties.Fallback,
                                    properties.GraphicsStyleId);

                // Pre-release code from DevDays

                //DirectShape ds = DirectShape.CreateElement(
                //  doc, result.GetGeometricalObjects(), "A", "B");

                //ds.SetCategoryId(new ElementId(
                //  BuiltInCategory.OST_GenericModel));

                // Code updated for Revit UR1

                ElementId   categoryId = new ElementId(BuiltInCategory.OST_GenericModel);
                DirectShape ds         = DirectShape.CreateElement(doc, categoryId, "A", "B");
                ds.SetShape(result.GetGeometricalObjects());
                ds.Name = stlDocumentName;

                t.Commit();
            }
        }
Ejemplo n.º 5
0
        public List <PlanarFace> GetMeshedFaces()
        {
            Mesh mesh = GetMesh();
            TessellatedShapeBuilder builder
                = new TessellatedShapeBuilder();

            builder.OpenConnectedFaceSet(false);

            List <XYZ> args = new List <XYZ>(3);

            XYZ[] triangleCorners = new XYZ[3];

            for (int i = 0; i < mesh.NumTriangles; ++i)
            {
                MeshTriangle triangle = mesh.get_Triangle(i);

                triangleCorners[0] = triangle.get_Vertex(0);
                triangleCorners[1] = triangle.get_Vertex(1);
                triangleCorners[2] = triangle.get_Vertex(2);

                TessellatedFace tesseFace
                    = new TessellatedFace(triangleCorners,
                                          ElementId.InvalidElementId);

                if (builder.DoesFaceHaveEnoughLoopsAndVertices(
                        tesseFace))
                {
                    builder.AddFace(tesseFace);
                }
            }

            builder.CloseConnectedFaceSet();

            TessellatedShapeBuilderResult result
                = builder.Build(
                      TessellatedShapeBuilderTarget.AnyGeometry,
                      TessellatedShapeBuilderFallback.Mesh,
                      ElementId.InvalidElementId);

            var geo = result.GetGeometricalObjects();

            var solids = GeoHelper.GetSolidsInModel(geo, GeoHelper.SolidVolumnConstraint.Any);
            var faces  = GeoHelper.GetSurfaces(solids.Keys);

            return(faces.OfType <PlanarFace>().ToList());
        }
Ejemplo n.º 6
0
        private void Execute(IEnumerable <List <XYZ> > triangles)
        {
            void Run(Document doc)
            {
                TessellatedShapeBuilder builder = new TessellatedShapeBuilder();

                builder.OpenConnectedFaceSet(false);

                foreach (List <XYZ> triangle in triangles)
                {
                    TessellatedFace tessellatedFace = new TessellatedFace(triangle, ElementId.InvalidElementId);

                    if (builder.DoesFaceHaveEnoughLoopsAndVertices(tessellatedFace))
                    {
                        builder.AddFace(tessellatedFace);
                    }
                }

                builder.CloseConnectedFaceSet();
                builder.Target   = TessellatedShapeBuilderTarget.AnyGeometry;
                builder.Fallback = TessellatedShapeBuilderFallback.Mesh;
                builder.Build();

                TessellatedShapeBuilderResult result = builder.GetBuildResult();

                //var ds = DirectShape.CreateElement(doc, new ElementId(BuiltInCategory.OST_GenericModel));

                //ds.ApplicationId = Assembly.GetExecutingAssembly().GetType().GUID.ToString();
                //ds.ApplicationDataId = Guid.NewGuid().ToString();
                //ds.Name = "NavisWorksShape";
                //DirectShapeOptions dsOptions = ds.GetOptions();
                //dsOptions.ReferencingOption = DirectShapeReferencingOption.Referenceable;
                //ds.SetOptions(dsOptions);

                //ds.SetShape(result.GetGeometricalObjects());
                CreateDirectShape(doc, result.GetGeometricalObjects());
            }

            _eventHandler.Action          = Run;
            _eventHandler.TransactionName = "Importing navisWorks elements";

            _externalEvent.Raise();
        }
Ejemplo n.º 7
0
        public static void Execute(
            ExternalCommandData commandData)
        {
            UIApplication uiapp   = commandData.Application;
            UIDocument    uidoc   = uiapp.ActiveUIDocument;
            Document      doc     = uidoc.Document;
            Selection     choices = uidoc.Selection;

            try
            {
                Reference reference = choices.PickObject(
                    ObjectType.Face);

                Element el = doc.GetElement(
                    reference.ElementId);

                Face face = el.GetGeometryObjectFromReference(
                    reference) as Face;

                Mesh mesh = face.Triangulate();

                var familyInstance = el as FamilyInstance;

                if (null != familyInstance)
                {
                    var t = familyInstance
                            .GetTotalTransform();

                    mesh = mesh.get_Transformed(t);
                }

                using (Transaction trans = new Transaction(doc))
                {
                    trans.Start("Create DirectShape from Face");

                    TessellatedShapeBuilder builder
                        = new TessellatedShapeBuilder();

                    builder.OpenConnectedFaceSet(false);

                    List <XYZ> args = new List <XYZ>(3);

                    XYZ[] triangleCorners = new XYZ[3];

                    for (int i = 0; i < mesh.NumTriangles; ++i)
                    {
                        MeshTriangle triangle = mesh.get_Triangle(i);

                        triangleCorners[0] = triangle.get_Vertex(0);
                        triangleCorners[1] = triangle.get_Vertex(1);
                        triangleCorners[2] = triangle.get_Vertex(2);

                        TessellatedFace tesseFace
                            = new TessellatedFace(triangleCorners,
                                                  ElementId.InvalidElementId);

                        if (builder.DoesFaceHaveEnoughLoopsAndVertices(
                                tesseFace))
                        {
                            builder.AddFace(tesseFace);
                        }
                    }

                    builder.CloseConnectedFaceSet();

                    //TessellatedShapeBuilderResult result
                    //  = builder.Build(
                    //    TessellatedShapeBuilderTarget.AnyGeometry,
                    //    TessellatedShapeBuilderFallback.Mesh,
                    //    ElementId.InvalidElementId ); // 2016

                    builder.Target   = TessellatedShapeBuilderTarget.AnyGeometry;    // 2018
                    builder.Fallback = TessellatedShapeBuilderFallback.Mesh;         // 2018

                    builder.Build();                                                 // 2018

                    TessellatedShapeBuilderResult result = builder.GetBuildResult(); // 2018

                    ElementId categoryId = new ElementId(
                        BuiltInCategory.OST_GenericModel);

                    //DirectShape ds = DirectShape.CreateElement(
                    //  doc, categoryId,
                    //  Assembly.GetExecutingAssembly().GetType()
                    //    .GUID.ToString(), Guid.NewGuid().ToString() ); // 2016

                    DirectShape ds = DirectShape.CreateElement(
                        doc, categoryId); // 2018

                    ds.ApplicationId = Assembly.GetExecutingAssembly()
                                       .GetType().GUID.ToString();    // 2018

                    ds.ApplicationDataId = Guid.NewGuid().ToString(); // 2018

                    ds.SetShape(result.GetGeometricalObjects());

                    ds.Name = "MyShape";

                    trans.Commit();
                }
            }
            catch (Exception ex)
            {
                Debug.Print(ex.Message);
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Create a new list of geometry objects from the
        /// given input. As input, we supply the result of
        /// Room.GetClosedShell. The output is the exact
        /// same solid lacking whatever flaws are present
        /// in the input solid.
        /// </summary>
        static IList <GeometryObject> CopyGeometry(
            GeometryElement geo,
            ElementId materialId,
            List <IntPoint3d> coords,
            List <TriangleIndices> indices)
        {
            TessellatedShapeBuilderResult result = null;

            TessellatedShapeBuilder builder
                = new TessellatedShapeBuilder();

            // Need to include the key in the value, otherwise
            // no way to access it later, cf.
            // https://stackoverflow.com/questions/1619090/getting-a-keyvaluepair-directly-from-a-dictionary

            Dictionary <XYZ, KeyValuePair <XYZ, int> > pts
                = new Dictionary <XYZ, KeyValuePair <XYZ, int> >(
                      new XyzEqualityComparer());

            int nSolids = 0;
            //int nFaces = 0;
            int nTriangles = 0;
            //int nVertices = 0;
            List <XYZ> vertices = new List <XYZ>(3);

            foreach (GeometryObject obj in geo)
            {
                Solid solid = obj as Solid;

                if (null != solid)
                {
                    if (0 < solid.Volume)
                    {
                        ++nSolids;

                        builder.OpenConnectedFaceSet(false);

                        #region Create a new solid based on tessellation of the invalid room closed shell solid
#if CREATE_NEW_SOLID_USING_TESSELATION
                        Debug.Assert(
                            SolidUtils.IsValidForTessellation(solid),
                            "expected a valid solid for room closed shell");

                        SolidOrShellTessellationControls controls
                            = new SolidOrShellTessellationControls()
                            {
                            //
                            // Summary:
                            //     A positive real number specifying how accurately a triangulation should approximate
                            //     a solid or shell.
                            //
                            // Exceptions:
                            //   T:Autodesk.Revit.Exceptions.ArgumentOutOfRangeException:
                            //     When setting this property: The given value for accuracy must be greater than
                            //     0 and no more than 30000 feet.
                            // This statement is not true. I set Accuracy = 0.003 and an exception was thrown.
                            // Setting it to 0.006 was acceptable. 0.03 is a bit over 9 mm.
                            //
                            // Remarks:
                            //     The maximum distance from a point on the triangulation to the nearest point on
                            //     the solid or shell should be no greater than the specified accuracy. This constraint
                            //     may be approximately enforced.
                            Accuracy = 0.03,
                            //
                            // Summary:
                            //     An number between 0 and 1 (inclusive) specifying the level of detail for the
                            //     triangulation of a solid or shell.
                            //
                            // Exceptions:
                            //   T:Autodesk.Revit.Exceptions.ArgumentOutOfRangeException:
                            //     When setting this property: The given value for levelOfDetail must lie between
                            //     0 and 1 (inclusive).
                            //
                            // Remarks:
                            //     Smaller values yield coarser triangulations (fewer triangles), while larger values
                            //     yield finer triangulations (more triangles).
                            LevelOfDetail = 0.1,
                            //
                            // Summary:
                            //     A non-negative real number specifying the minimum allowed angle for any triangle
                            //     in the triangulation, in radians.
                            //
                            // Exceptions:
                            //   T:Autodesk.Revit.Exceptions.ArgumentOutOfRangeException:
                            //     When setting this property: The given value for minAngleInTriangle must be at
                            //     least 0 and less than 60 degrees, expressed in radians. The value 0 means to
                            //     ignore the minimum angle constraint.
                            //
                            // Remarks:
                            //     A small value can be useful when triangulating long, thin objects, in order to
                            //     keep the number of triangles small, but it can result in long, thin triangles,
                            //     which are not acceptable for all applications. If the value is too large, this
                            //     constraint may not be satisfiable, causing the triangulation to fail. This constraint
                            //     may be approximately enforced. A value of 0 means to ignore the minimum angle
                            //     constraint.
                            MinAngleInTriangle = 3 * Math.PI / 180.0,
                            //
                            // Summary:
                            //     A positive real number specifying the minimum allowed value for the external
                            //     angle between two adjacent triangles, in radians.
                            //
                            // Exceptions:
                            //   T:Autodesk.Revit.Exceptions.ArgumentOutOfRangeException:
                            //     When setting this property: The given value for minExternalAngleBetweenTriangles
                            //     must be greater than 0 and no more than 30000 feet.
                            //
                            // Remarks:
                            //     A small value yields more smoothly curved triangulated surfaces, usually at the
                            //     expense of an increase in the number of triangles. Note that this setting has
                            //     no effect for planar surfaces. This constraint may be approximately enforced.
                            MinExternalAngleBetweenTriangles = 0.2 * Math.PI
                            };

                        TriangulatedSolidOrShell shell
                            = SolidUtils.TessellateSolidOrShell(solid, controls);

                        int n = shell.ShellComponentCount;

                        Debug.Assert(1 == n,
                                     "expected just one shell component in room closed shell");

                        TriangulatedShellComponent component
                            = shell.GetShellComponent(0);

                        int coordsBase  = coords.Count;
                        int indicesBase = indices.Count;

                        n = component.VertexCount;

                        for (int i = 0; i < n; ++i)
                        {
                            XYZ v = component.GetVertex(i);
                            coords.Add(new IntPoint3d(v));
                        }

                        n = component.TriangleCount;

                        for (int i = 0; i < n; ++i)
                        {
                            TriangleInShellComponent t
                                = component.GetTriangle(i);

                            vertices.Clear();

                            vertices.Add(component.GetVertex(t.VertexIndex0));
                            vertices.Add(component.GetVertex(t.VertexIndex1));
                            vertices.Add(component.GetVertex(t.VertexIndex2));

                            indices.Add(new TriangleIndices(
                                            coordsBase + t.VertexIndex0,
                                            coordsBase + t.VertexIndex1,
                                            coordsBase + t.VertexIndex2));

                            TessellatedFace tf = new TessellatedFace(
                                vertices, materialId);

                            if (builder.DoesFaceHaveEnoughLoopsAndVertices(tf))
                            {
                                builder.AddFace(tf);
                                ++nTriangles;
                            }
                        }
#else
                        // Iterate over the individual solid faces

                        foreach (Face f in solid.Faces)
                        {
                            vertices.Clear();

                            #region Use face triangulation
#if USE_FACE_TRIANGULATION
                            Mesh mesh = f.Triangulate();
                            int  n    = mesh.NumTriangles;

                            for (int i = 0; i < n; ++i)
                            {
                                MeshTriangle triangle = mesh.get_Triangle(i);

                                XYZ p1 = triangle.get_Vertex(0);
                                XYZ p2 = triangle.get_Vertex(1);
                                XYZ p3 = triangle.get_Vertex(2);

                                vertices.Clear();
                                vertices.Add(p1);
                                vertices.Add(p2);
                                vertices.Add(p3);

                                TessellatedFace tf
                                    = new TessellatedFace(
                                          vertices, materialId);

                                if (builder.DoesFaceHaveEnoughLoopsAndVertices(tf))
                                {
                                    builder.AddFace(tf);
                                    ++nTriangles;
                                }
                            }
#endif // USE_FACE_TRIANGULATION
                            #endregion // Use face triangulation

                            #region Use original solid and its EdgeLoops
#if USE_EDGELOOPS
                            // This returns arbitrarily ordered and
                            // oriented edges, so no solid can be
                            // generated.

                            foreach (EdgeArray loop in f.EdgeLoops)
                            {
                                foreach (Edge e in loop)
                                {
                                    XYZ p = e.AsCurve().GetEndPoint(0);
                                    XYZ q = p;

                                    if (pts.ContainsKey(p))
                                    {
                                        KeyValuePair <XYZ, int> kv = pts[p];
                                        q = kv.Key;
                                        int n = kv.Value;
                                        pts[p] = new KeyValuePair <XYZ, int>(
                                            q, ++n);

                                        Debug.Print("Ignoring vertex at {0} "
                                                    + "with distance {1} to existing "
                                                    + "vertex {2}",
                                                    p, p.DistanceTo(q), q);
                                    }
                                    else
                                    {
                                        pts[p] = new KeyValuePair <XYZ, int>(
                                            p, 1);
                                    }

                                    vertices.Add(q);
                                    ++nVertices;
                                }
                            }
#endif // USE_EDGELOOPS
                            #endregion // Use original solid and its EdgeLoops

                            #region Use original solid and GetEdgesAsCurveLoops
#if USE_AS_CURVE_LOOPS
                            // The solids generated by this have some weird
                            // normals, so they do not render correctly in
                            // the Forge viewer. Revert to triangles again.

                            IList <CurveLoop> loops
                                = f.GetEdgesAsCurveLoops();

                            foreach (CurveLoop loop in loops)
                            {
                                foreach (Curve c in loop)
                                {
                                    XYZ p = c.GetEndPoint(0);
                                    XYZ q = p;

                                    if (pts.ContainsKey(p))
                                    {
                                        KeyValuePair <XYZ, int> kv = pts[p];
                                        q = kv.Key;
                                        int n = kv.Value;
                                        pts[p] = new KeyValuePair <XYZ, int>(
                                            q, ++n);

                                        Debug.Print("Ignoring vertex at {0} "
                                                    + "with distance {1} to existing "
                                                    + "vertex {2}",
                                                    p, p.DistanceTo(q), q);
                                    }
                                    else
                                    {
                                        pts[p] = new KeyValuePair <XYZ, int>(
                                            p, 1);
                                    }

                                    vertices.Add(q);
                                    ++nVertices;
                                }
                            }
#endif // USE_AS_CURVE_LOOPS
                            #endregion // Use original solid and GetEdgesAsCurveLoops

                            builder.AddFace(new TessellatedFace(
                                                vertices, materialId));

                            ++nFaces;
                        }
#endif // CREATE_NEW_SOLID_USING_TESSELATION
                        #endregion // Create a new solid based on tessellation of the invalid room closed shell solid

                        builder.CloseConnectedFaceSet();
                        builder.Target   = TessellatedShapeBuilderTarget.AnyGeometry; // Solid failed
                        builder.Fallback = TessellatedShapeBuilderFallback.Mesh;      // use Abort if target is Solid
                        builder.Build();
                        result = builder.GetBuildResult();

                        // Debug printout log of current solid's glTF facet data

                        n = coords.Count - coordsBase;

                        Debug.Print("{0} glTF vertex coordinates "
                                    + "in millimetres:", n);

                        Debug.Print(string.Join(" ", coords
                                                .TakeWhile <IntPoint3d>((p, i) => coordsBase <= i)
                                                .Select <IntPoint3d, string>(p => p.ToString())));

                        n = indices.Count - indicesBase;

                        Debug.Print("{0} glTF triangles:", n);

                        Debug.Print(string.Join(" ", indices
                                                .TakeWhile <TriangleIndices>((ti, i) => indicesBase <= i)
                                                .Select <TriangleIndices, string>(ti => ti.ToString())));
                    }
                }
            }
            return(result.GetGeometricalObjects());
        }
Ejemplo n.º 9
0
        private static IList <GeometryObject> GetGeometryObjectsFromFace(Face face)
        {
            IList <GeometryObject> shapeGeometries = null;

            try
            {
                List <CurveLoop> profiles = new List <CurveLoop>();
                XYZ normal = face.ComputeNormal(new UV(0, 0));

                IList <CurveLoop>          curveLoops       = face.GetEdgesAsCurveLoops();
                IList <IList <CurveLoop> > sortedCurveLoops = ExporterIFCUtils.SortCurveLoops(curveLoops);
                foreach (IList <CurveLoop> curveLoopList in sortedCurveLoops)
                {
                    foreach (CurveLoop curveLoop in curveLoopList)
                    {
                        if (curveLoop.IsCounterclockwise(normal))
                        {
                            profiles.Insert(0, curveLoop);
                        }
                        else
                        {
                            profiles.Add(curveLoop);
                        }
                    }
                }

                List <List <XYZ> > allLoopVertices = new List <List <XYZ> >();
                for (int i = 0; i < profiles.Count; i++)
                {
                    List <XYZ> vertices  = new List <XYZ>();
                    CurveLoop  curveLoop = profiles[i];
                    foreach (Curve curve in curveLoop)
                    {
                        IList <XYZ> tessellatedVertices = curve.Tessellate();
                        tessellatedVertices.RemoveAt(tessellatedVertices.Count - 1);
                        vertices.AddRange(tessellatedVertices);
                    }
                    allLoopVertices.Add(vertices);
                }

                TessellatedShapeBuilder builder = new TessellatedShapeBuilder();
                builder.OpenConnectedFaceSet(false);

                TessellatedFace tesseFace = new TessellatedFace(allLoopVertices.ToArray(), ElementId.InvalidElementId);
                if (builder.DoesFaceHaveEnoughLoopsAndVertices(tesseFace))
                {
                    builder.AddFace(tesseFace);
                }

                builder.CloseConnectedFaceSet();
#if RELEASE2015 || RELEASE2016
                TessellatedShapeBuilderResult result = builder.Build(TessellatedShapeBuilderTarget.AnyGeometry, TessellatedShapeBuilderFallback.Mesh, ElementId.InvalidElementId);
#else
                builder.Target   = TessellatedShapeBuilderTarget.AnyGeometry;
                builder.Fallback = TessellatedShapeBuilderFallback.Mesh;
                builder.Build();
                TessellatedShapeBuilderResult result = builder.GetBuildResult();
#endif
                shapeGeometries = result.GetGeometricalObjects();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Failed to get geometry objects from a face.\n" + ex.Message, "Get Geometry Objects", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
            return(shapeGeometries);
        }
Ejemplo n.º 10
0
        // Create a pyramid-shaped DirectShape using given material for the faces
        static public void CreateTessellatedShape(Document doc, ElementId materialId)
        {
            List <XYZ> loopVertices = new List <XYZ>(4);

            TessellatedShapeBuilder builder = new TessellatedShapeBuilder();

            builder.OpenConnectedFaceSet(true);
            // create a pyramid with a square base 4' x 4' and 5' high
            double length = 4.0;
            double height = 5.0;

            XYZ basePt1 = XYZ.Zero;
            XYZ basePt2 = new XYZ(length, 0, 0);
            XYZ basePt3 = new XYZ(length, length, 0);
            XYZ basePt4 = new XYZ(0, length, 0);
            XYZ apex    = new XYZ(length / 2, length / 2, height);

            loopVertices.Add(basePt1);
            loopVertices.Add(basePt2);
            loopVertices.Add(basePt3);
            loopVertices.Add(basePt4);
            builder.AddFace(new TessellatedFace(loopVertices, materialId));

            loopVertices.Clear();
            loopVertices.Add(basePt1);
            loopVertices.Add(apex);
            loopVertices.Add(basePt2);
            builder.AddFace(new TessellatedFace(loopVertices, materialId));

            loopVertices.Clear();
            loopVertices.Add(basePt2);
            loopVertices.Add(apex);
            loopVertices.Add(basePt3);
            builder.AddFace(new TessellatedFace(loopVertices, materialId));

            loopVertices.Clear();
            loopVertices.Add(basePt3);
            loopVertices.Add(apex);
            loopVertices.Add(basePt4);
            builder.AddFace(new TessellatedFace(loopVertices, materialId));

            loopVertices.Clear();
            loopVertices.Add(basePt4);
            loopVertices.Add(apex);
            loopVertices.Add(basePt1);
            builder.AddFace(new TessellatedFace(loopVertices, materialId));

            builder.CloseConnectedFaceSet();
            builder.Target   = TessellatedShapeBuilderTarget.Solid;
            builder.Fallback = TessellatedShapeBuilderFallback.Abort;
            builder.Build();

            TessellatedShapeBuilderResult result = builder.GetBuildResult();

            using (Transaction t = new Transaction(doc, "Create tessellated direct shape"))
            {
                t.Start();

                DirectShape ds = DirectShape.CreateElement(doc, new ElementId(BuiltInCategory.OST_GenericModel));
                ds.ApplicationId     = "Application id";
                ds.ApplicationDataId = "Geometry object id";

                ds.SetShape(result.GetGeometricalObjects());
                t.Commit();
            }
        }
Ejemplo n.º 11
0
        public static void CreateCube(Document doc, XYZ min, XYZ max, string name)
        {
            List <XYZ> loopVertices = new List <XYZ>(4);

            TessellatedShapeBuilder builder = new TessellatedShapeBuilder();

            builder.OpenConnectedFaceSet(true);

            XYZ topLeftBack     = new XYZ(min.X, max.Y, min.Z);
            XYZ topRightBack    = new XYZ(max.X, max.Y, min.Z);
            XYZ bottomLeftBack  = new XYZ(min.X, min.Y, min.Z); //min
            XYZ bottomRightBack = new XYZ(max.X, min.Y, min.Z);

            XYZ topLeftFront     = new XYZ(min.X, max.Y, max.Z);
            XYZ topRightFront    = new XYZ(max.X, max.Y, max.Z); //max
            XYZ bottomLeftFront  = new XYZ(min.X, min.Y, max.Z);
            XYZ bottomRightFront = new XYZ(max.X, min.Y, max.Z);


            //Create the material
            ElementId materialId = ElementId.InvalidElementId;

            loopVertices.Add(topLeftBack);
            loopVertices.Add(topRightBack);
            loopVertices.Add(topRightFront);
            loopVertices.Add(topLeftFront);
            builder.AddFace(new TessellatedFace(loopVertices, materialId));

            loopVertices.Clear();
            loopVertices.Add(bottomLeftBack);
            loopVertices.Add(bottomRightBack);
            loopVertices.Add(bottomRightFront);
            loopVertices.Add(bottomLeftFront);
            builder.AddFace(new TessellatedFace(loopVertices, materialId));

            loopVertices.Clear();
            loopVertices.Add(topLeftBack);
            loopVertices.Add(topLeftFront);
            loopVertices.Add(bottomLeftFront);
            loopVertices.Add(bottomLeftBack);
            builder.AddFace(new TessellatedFace(loopVertices, materialId));

            loopVertices.Clear();
            loopVertices.Add(topLeftBack);
            loopVertices.Add(topLeftFront);
            loopVertices.Add(bottomRightFront);
            loopVertices.Add(bottomRightBack);
            builder.AddFace(new TessellatedFace(loopVertices, materialId));

            loopVertices.Clear();
            loopVertices.Add(topLeftBack);
            loopVertices.Add(topRightBack);
            loopVertices.Add(bottomRightBack);
            loopVertices.Add(bottomLeftBack);
            builder.AddFace(new TessellatedFace(loopVertices, materialId));

            loopVertices.Clear();
            loopVertices.Add(topLeftFront);
            loopVertices.Add(topRightFront);
            loopVertices.Add(bottomRightFront);
            loopVertices.Add(bottomLeftFront);
            builder.AddFace(new TessellatedFace(loopVertices, materialId));

            builder.CloseConnectedFaceSet();

            builder.Build();
            TessellatedShapeBuilderResult result = builder.GetBuildResult();

            using (Transaction t = new Transaction(doc, "Create tessellated direct shape"))
            {
                t.Start();

                DirectShape ds = DirectShape.CreateElement(doc, new ElementId(BuiltInCategory.OST_GenericModel));
                ds.Name = name;
                ds.SetShape(result.GetGeometricalObjects());
                t.Commit();
            }
        }
Ejemplo n.º 12
0
        public static void Execute1(
            ExternalCommandData commandData)
        {
            Transaction trans = null;

            UIDocument uidoc = commandData.Application
                               .ActiveUIDocument;

            Document doc = uidoc.Document;

            try
            {
                Selection choices = uidoc.Selection;

                Reference reference = choices.PickObject(
                    ObjectType.Face);

                Element el = doc.GetElement(
                    reference.ElementId);

                trans = new Transaction(doc, "Create elements");
                trans.Start();

                TessellatedShapeBuilder builder
                    = new TessellatedShapeBuilder();

                builder.OpenConnectedFaceSet(false);

                Face face = el.GetGeometryObjectFromReference(
                    reference) as Face;

                Mesh       mesh = face.Triangulate();
                List <XYZ> args = new List <XYZ>(3);

                XYZ offset = new XYZ();
                if (el.Location is LocationPoint)
                {
                    LocationPoint locationPoint = el.Location
                                                  as LocationPoint;
                    offset = locationPoint.Point;
                }

                for (int i = 0; i < mesh.NumTriangles; i++)
                {
                    MeshTriangle triangle = mesh.get_Triangle(
                        i);

                    XYZ p1 = triangle.get_Vertex(0);
                    XYZ p2 = triangle.get_Vertex(1);
                    XYZ p3 = triangle.get_Vertex(2);

                    p1 = p1.Add(offset);
                    p2 = p2.Add(offset);
                    p3 = p3.Add(offset);

                    args.Clear();
                    args.Add(p1);
                    args.Add(p2);
                    args.Add(p3);

                    TessellatedFace tesseFace
                        = new TessellatedFace(args,
                                              ElementId.InvalidElementId);

                    if (builder.DoesFaceHaveEnoughLoopsAndVertices(
                            tesseFace))
                    {
                        builder.AddFace(tesseFace);
                    }
                }

                builder.CloseConnectedFaceSet();

                //TessellatedShapeBuilderResult result
                //  = builder.Build(
                //    TessellatedShapeBuilderTarget.AnyGeometry,
                //    TessellatedShapeBuilderFallback.Mesh,
                //    ElementId.InvalidElementId ); // 2016

                builder.Target   = TessellatedShapeBuilderTarget.AnyGeometry;    // 2018
                builder.Fallback = TessellatedShapeBuilderFallback.Mesh;         // 2018

                builder.Build();                                                 // 2018

                TessellatedShapeBuilderResult result = builder.GetBuildResult(); // 2018

                ElementId categoryId = new ElementId(
                    BuiltInCategory.OST_GenericModel);

                //DirectShape ds = DirectShape.CreateElement(
                //  doc, categoryId,
                //  Assembly.GetExecutingAssembly().GetType()
                //  .GUID.ToString(), Guid.NewGuid().ToString() ); // 2016

                DirectShape ds = DirectShape.CreateElement(
                    doc, categoryId); // 2018

                ds.ApplicationId = Assembly.GetExecutingAssembly()
                                   .GetType().GUID.ToString();    // 2018

                ds.ApplicationDataId = Guid.NewGuid().ToString(); // 2018

                ds.SetShape(result.GetGeometricalObjects());

                ds.Name = "MyShape";

                trans.Commit();
            }
            catch (Exception ex)
            {
                if (trans != null)
                {
                    trans.RollBack();
                }

                Debug.Print(ex.Message);
            }
        }
Ejemplo n.º 13
0
        static internal IEnumerable <GeometryObject> Convert(IEnumerable <Rhino.Geometry.Mesh> meshes)
        {
            List <XYZ> faceVertices = new List <XYZ>(4);

            var builder = new TessellatedShapeBuilder();

            builder.Target   = TessellatedShapeBuilderTarget.AnyGeometry;
            builder.Fallback = TessellatedShapeBuilderFallback.Mesh;

            foreach (var mesh in meshes)
            {
                Rhino.Geometry.Mesh[] pieces = mesh.DisjointMeshCount > 1 ?
                                               mesh.SplitDisjointPieces() :
                                               new Rhino.Geometry.Mesh[] { mesh };

                foreach (var piece in pieces)
                {
                    // Meshes with edges smaller than AbsoluteRevitTolerance (1/16 inch) are not welcome in Revit
                    while (piece.CollapseFacesByEdgeLength(false, ModelAbsoluteTolerance) > 0)
                    {
                        ;
                    }

                    piece.Faces.ConvertNonPlanarQuadsToTriangles(RhinoMath.ZeroTolerance, RhinoMath.UnsetValue, 5);

                    bool isOriented  = false;
                    bool hasBoundary = false;
                    bool isSolid     = piece.IsClosed && piece.IsManifold(true, out isOriented, out hasBoundary) && isOriented;
                    var  vertices    = piece.Vertices;

                    builder.OpenConnectedFaceSet(isSolid);
                    foreach (var face in piece.Faces)
                    {
                        faceVertices.Add(Convert(vertices[face.A]));
                        faceVertices.Add(Convert(vertices[face.B]));
                        faceVertices.Add(Convert(vertices[face.C]));
                        if (face.IsQuad)
                        {
                            faceVertices.Add(Convert(vertices[face.D]));
                        }

                        builder.AddFace(new TessellatedFace(faceVertices, ElementId.InvalidElementId));
                        faceVertices.Clear();
                    }
                    builder.CloseConnectedFaceSet();
                }
            }

            try
            {
                builder.Build();
            }
            catch (Autodesk.Revit.Exceptions.ApplicationException e)
            {
                Debug.Fail(e.Source, e.Message);
                return(null);
            }

            TessellatedShapeBuilderResult result = builder.GetBuildResult();

            return(result.GetGeometricalObjects());
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Create a new DirectShape element from given
        /// list of faces and return the number of faces
        /// processed.
        /// Return -1 if a face vertex index exceeds the
        /// total number of available vertices,
        /// representing a fatal error.
        /// </summary>
        public static DirectShape NewDirectShape(
            //List<XYZ> vertices,
            Autodesk.DesignScript.Geometry.Mesh mesh,
            //FaceCollection faces,
            //UIDocument UIdoc,
            //ElementId graphicsStyleId,
            //string appGuid,
            string shapeName)
        {
            int nFaces       = 0;
            int nFacesFailed = 0;

            Document doc = DocumentManager.Instance.CurrentDBDocument;

            string appGuid = doc.Application.ActiveAddInId.GetGUID().ToString();

            // Retrieve "<Sketch>" graphics style,
            // if it exists.

            FilteredElementCollector collector
                = new FilteredElementCollector(doc)
                  .OfClass(typeof(GraphicsStyle));

            GraphicsStyle style
                = collector.Cast <GraphicsStyle>()
                  .FirstOrDefault <GraphicsStyle>(gs
                                                  => gs.Name.Equals("<Sketch>"));

            ElementId graphicsStyleId = null;

            if (style != null)
            {
                graphicsStyleId = style.Id;
            }


            TessellatedShapeBuilder builder
                = new TessellatedShapeBuilder();

            builder.LogString = shapeName;

            List <Autodesk.DesignScript.Geometry.Point> corners = new List <Autodesk.DesignScript.Geometry.Point>(4);
            List <XYZ> XYZcorners = new List <XYZ>(4);

            builder.OpenConnectedFaceSet(false);

            // foreach (Face f in faces)
            //{
            builder.LogInteger = nFaces;

            if (corners.Capacity < mesh.FaceIndices.Length)
            {
                corners    = new List <Autodesk.DesignScript.Geometry.Point>(mesh.FaceIndices.Length);
                XYZcorners = new List <XYZ>(mesh.FaceIndices.Length);
            }

            corners.Clear();
            XYZcorners.Clear();

            foreach (IndexGroup i in mesh.FaceIndices)
            {
                //Debug.Assert(vertices.Count > i.vertex,
                //  "how can the face vertex index be larger "
                //  + "than the total number of vertices?");

                corners.Add(mesh.VertexPositions[i.A]);
                XYZcorners.Add(new XYZ(mesh.VertexPositions[(int)i.A].X, mesh.VertexPositions[(int)i.A].Y,
                                       mesh.VertexPositions[(int)i.A].Z));
                corners.Add(mesh.VertexPositions[(int)i.B]);
                XYZcorners.Add(new XYZ(mesh.VertexPositions[(int)i.B].X, mesh.VertexPositions[(int)i.B].Y,
                                       mesh.VertexPositions[(int)i.B].Z));
                corners.Add(mesh.VertexPositions[(int)i.C]);
                XYZcorners.Add(new XYZ(mesh.VertexPositions[(int)i.C].X, mesh.VertexPositions[(int)i.C].Y,
                                       mesh.VertexPositions[(int)i.C].Z));

                if (i.Count > 3)
                {
                    corners.Add(mesh.VertexPositions[(int)i.D]);
                    XYZcorners.Add(new XYZ(mesh.VertexPositions[(int)i.D].X, mesh.VertexPositions[(int)i.D].Y,
                                           mesh.VertexPositions[(int)i.D].Z));
                }
            }



            try
            {
                builder.AddFace(new TessellatedFace(XYZcorners,
                                                    ElementId.InvalidElementId));

                ++nFaces;
            }
            catch (Autodesk.Revit.Exceptions.ArgumentException ex)
            {
                // Remember something went wrong here.

                ++nFacesFailed;

                Debug.Print(
                    "Revit API argument exception {0}\r\n"
                    + "Failed to add face with {1} corners: {2}",
                    ex.Message, corners.Count,
                    string.Join(", ",
                                XYZcorners.Select <XYZ, string>(
                                    p => Util.PointString(p))));
            }
            //}

            builder.CloseConnectedFaceSet();

            // Refer to StlImport sample for more clever
            // handling of target and fallback and the
            // possible combinations.

            TessellatedShapeBuilderResult r
                = builder.Build(
                      TessellatedShapeBuilderTarget.Mesh,
                      TessellatedShapeBuilderFallback.Salvage,
                      graphicsStyleId);

            ConversionLog myLog = new ConversionLog("c:\\conversionLogFileName.txt");

            DataConversionMonitorScope myLoggingScope = new DataConversionMonitorScope(myLog);

            TessellatedShapeBuilderOutcome testOutcome = r.Outcome;
            IList <GeometryObject>         test        = r.GetGeometricalObjects();


            try
            {
                TransactionManager.Instance.EnsureInTransaction(DocumentManager.Instance.CurrentDBDocument);

                DirectShape ds = DirectShape.CreateElement(
                    doc, _categoryId, appGuid, shapeName);

                ds.SetShape(r.GetGeometricalObjects());
                ds.Name = shapeName;

                Debug.Print(
                    "Shape '{0}': added {1} face{2}, {3} face{4} failed.",
                    shapeName, nFaces, Util.PluralSuffix(nFaces),
                    nFacesFailed, Util.PluralSuffix(nFacesFailed));

                TransactionManager.Instance.TransactionTaskDone();

                return(ds);
            }
            catch (Exception ex)
            {
                Debug.Print(
                    "Problem with adding DirectShape: " + ex.Message.ToString());

                return(null);
            }
        }
Ejemplo n.º 15
0
        public static void Execute(
            ExternalCommandData commandData)
        {
            Transaction trans = null;

            UIApplication uiapp = commandData.Application;
            UIDocument    uidoc = uiapp.ActiveUIDocument;
            Document      doc   = uidoc.Document;

            try
            {
                Selection choices = uidoc.Selection;

                Reference faceref = choices.PickObject(
                    ObjectType.Face);

                string rep = faceref
                             .ConvertToStableRepresentation(doc);

                Debug.Assert(rep.EndsWith(":SURFACE"),
                             "expected stable representation to end with SURFACE");

                Debug.Print("Face reference picked: "
                            + rep);

                Element el = doc.GetElement(
                    faceref.ElementId);

                using (trans = new Transaction(doc))
                {
                    trans.Start("Create elements");

                    TessellatedShapeBuilder builder
                        = new TessellatedShapeBuilder();

                    builder.OpenConnectedFaceSet(false);

                    // This may return a face in the family
                    // symbol definition with no family instance
                    // transform applied. Use the GeometryElement
                    // GetTransformed method to retrieve the face
                    // with the instance transformation applied.

                    Face face = el.GetGeometryObjectFromReference(
                        faceref) as Face;

                    Debug.Print("Face reference property: "
                                + ((null == face.Reference)
              ? "<nil>"
              : face.Reference.ConvertToStableRepresentation(doc)));

                    Transform t = null;

                    FamilyInstance fi = el as FamilyInstance;

                    if (null != fi)
                    {
                        // Will this handle a face selected
                        // in a nested family instance?
                        // Some, yes, but not all.

                        //t = fi.GetTransform();

                        // This also works for some instances
                        // but not all.

                        //Transform t1 = fi.GetTotalTransform();

                        Options opt = new Options();
                        opt.ComputeReferences = true;

                        GeometryElement geo = el.get_Geometry(opt);

                        GeometryElement geo2 = geo.GetTransformed(
                            Transform.Identity);

                        Stack <Transform> tstack
                            = new Stack <Transform>();

                        if (GetTransformStackForObject(tstack,
                                                       geo, doc, rep) && 0 < tstack.Count)
                        {
                            Debug.Print("GetTransformStackForObject "
                                        + "returned true with tstack count {0}",
                                        tstack.Count);

                            t = Transform.Identity;

                            while (0 < tstack.Count)
                            {
                                t *= tstack.Pop();
                            }
                        }
                    }

                    Mesh mesh = face.Triangulate();

                    if (null != t)
                    {
                        mesh = mesh.get_Transformed(t);
                    }

                    XYZ[] triangleCorners = new XYZ[3];

                    for (int i = 0; i < mesh.NumTriangles; i++)
                    {
                        MeshTriangle triangle = mesh.get_Triangle(i);

                        triangleCorners[0] = triangle.get_Vertex(0);
                        triangleCorners[1] = triangle.get_Vertex(1);
                        triangleCorners[2] = triangle.get_Vertex(2);

                        XYZ normal = GetNormal(triangleCorners);

                        SketchPlane sketchPlane = GetSketchPlane(
                            doc, triangleCorners[0], normal);

                        DrawModelLineLoop(sketchPlane, triangleCorners);

                        TessellatedFace tesseFace
                            = new TessellatedFace(triangleCorners,
                                                  ElementId.InvalidElementId);

                        if (builder.DoesFaceHaveEnoughLoopsAndVertices(
                                tesseFace))
                        {
                            builder.AddFace(tesseFace);
                        }
                    }

                    builder.CloseConnectedFaceSet();

                    //TessellatedShapeBuilderResult result
                    //  = builder.Build(
                    //    TessellatedShapeBuilderTarget.AnyGeometry,
                    //    TessellatedShapeBuilderFallback.Mesh,
                    //    ElementId.InvalidElementId ); // 2016

                    builder.Target   = TessellatedShapeBuilderTarget.AnyGeometry;    // 2018
                    builder.Fallback = TessellatedShapeBuilderFallback.Mesh;         // 2018

                    builder.Build();                                                 // 2018

                    TessellatedShapeBuilderResult result = builder.GetBuildResult(); // 2018

                    ElementId categoryId = new ElementId(
                        BuiltInCategory.OST_GenericModel);

                    //DirectShape ds = DirectShape.CreateElement(
                    //  doc, categoryId,
                    //  Assembly.GetExecutingAssembly().GetType().GUID.ToString(),
                    //  Guid.NewGuid().ToString() ); // 2016

                    DirectShape ds = DirectShape.CreateElement(
                        doc, categoryId); // 2018

                    ds.ApplicationId = Assembly.GetExecutingAssembly()
                                       .GetType().GUID.ToString();    // 2018

                    ds.ApplicationDataId = Guid.NewGuid().ToString(); // 2018

                    ds.SetShape(result.GetGeometricalObjects());

                    ds.Name = "MyShape";

                    trans.Commit();
                }
            }
            catch (Exception ex)
            {
                TaskDialog.Show("Error", ex.Message);
            }
        }