Cant get geometry of touching Foundation elements.

Cant get geometry of touching Foundation elements.

zrodgersTSSSU
Advocate Advocate
285 Views
4 Replies
Message 1 of 5

Cant get geometry of touching Foundation elements.

zrodgersTSSSU
Advocate
Advocate

Good Morning Everyone, I have an intresting problem.  I am working on a plugin for concrete formwork takeoff, I have it working on all Slabs, beams, underslab, and inside of beams, however when I run it on the foundations it only works when the element is an isolated foundation. If two foundations are touching each other it wont find the foundations solids. The single foundation on the left ran though the whole script and generated the faces of the foundation as formwork but the ones that are touching dont get past line 328. When i am checking if the solid is null.

zrodgersTSSSU_0-1739546481974.pngzrodgersTSSSU_1-1739546496510.png

//FORMWORK ONLY FOUNDATIONS
                        if ((BuiltInCategory)elem.Category.Id.IntegerValue == BuiltInCategory.OST_StructuralFoundation)
                        {
                            Options opts = new Options();
                            GeometryElement geoElem = elem.get_Geometry(opts);

                            foreach (GeometryObject geoObj in geoElem)
                            {
                                GeometryInstance geoInst = geoObj as GeometryInstance;
                                if (null != geoInst)
                                {
                                    GeometryElement instGeoElem = geoInst.GetInstanceGeometry();
                                    if (instGeoElem != null)
                                    {
                                        foreach (GeometryObject o in instGeoElem)
                                        {
                                            Solid solid = o as Solid;
                                            foundationSolids.Add(solid);
                                            if (solid != null)
                                            {
                                                //TEST DIRECT SHAPE TO SEE IF ITS PICKING UP SOLIDS
                                                DirectShape ds1 = null;
                                                ds1 = DirectShape.CreateElement(doc, new ElementId(BuiltInCategory.OST_GenericModel));
                                                ds1.ApplicationId = "Application id";
                                                ds1.ApplicationDataId = "Geometry object id";
                                                ds1.Name = "FOUNDATION";
                                                ds1.SetShape(new GeometryObject[] { solid });
                                            }
                                        }
                                    }
                                }
                            }
0 Likes
Accepted solutions (2)
286 Views
4 Replies
Replies (4)
Message 2 of 5

jeremy_tammik
Alumni
Alumni
Accepted solution

One difference that might occur when solids touch: an isolated instance may be able to use the unmodified family symbol geometry; touching instances may not, so they are forced to generate their own specific instance geometry instead of reusing the default symbol geometry. Hard to say whether this might account for the differing behaviour. Might give you a lead on an aspect to check, though.

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
Message 3 of 5

zrodgersTSSSU
Advocate
Advocate

@jeremy_tammik Thank you for the quick response. I found a method to see if the geometry has been modified so i used that to separate the two different cases. It does create the direct shape for each of the joined foundation now but they are in the wrong location and directly on top of one another. Does using GetOriginalGeometry() effect location? (red arrow pointing to the two directshapes on top of eachother in the wrong location).

 

zrodgersTSSSU_0-1739551595565.png

zrodgersTSSSU_1-1739551696427.png

 

//FORMWORK ONLY FOUNDATIONS
                        if ((BuiltInCategory)elem.Category.Id.IntegerValue == BuiltInCategory.OST_StructuralFoundation)
                        {
                            if (elem is FamilyInstance famInst)
                            {
                                Options opts = new Options();
                                GeometryElement geoElem = elem.get_Geometry(opts);
                                GeometryElement originalGeometry = famInst.GetOriginalGeometry(opts);

                                //for family elements that are cut/joined
                                if (famInst.HasModifiedGeometry())
                                {
                                    foreach (GeometryObject geoObj in originalGeometry)
                                    {
                                        Solid solid = geoObj as Solid;
                                        if (solid != null && 0 < solid.Faces.Size)
                                        {
                                            foundationSolids.Add(solid);
                                            //TEST DIRECT SHAPE TO SEE IF ITS PICKING UP SOLIDS
                                            DirectShape ds1 = null;
                                            ds1 = DirectShape.CreateElement(doc, new ElementId(BuiltInCategory.OST_GenericModel));
                                            ds1.ApplicationId = "Application id";
                                            ds1.ApplicationDataId = "Geometry object id";
                                            ds1.Name = "FOUNDATION";
                                            ds1.SetShape(new GeometryObject[] { solid });
                                        }
                                    }

                                }
                                //for non-modified geometry
                                else
                                {
                                    foreach (GeometryObject geoObj in geoElem)
                                    {
                                        GeometryInstance geoInst = geoObj as GeometryInstance;
                                        if (null != geoInst)
                                        {
                                            GeometryElement instGeoElem = geoInst.GetInstanceGeometry();
                                            if (instGeoElem != null)
                                            {
                                                foreach (GeometryObject o in instGeoElem)
                                                {
                                                    Solid solid = o as Solid;
                                                    foundationSolids.Add(solid);
                                                    //double vol = solid.Volume;
                                                    //if (solid != null)
                                                    //{
                                                    //    //TEST DIRECT SHAPE TO SEE IF ITS PICKING UP SOLIDS
                                                    //    DirectShape ds1 = null;
                                                    //    ds1 = DirectShape.CreateElement(doc, new ElementId(BuiltInCategory.OST_GenericModel));
                                                    //    ds1.ApplicationId = "Application id";
                                                    //    ds1.ApplicationDataId = "Geometry object id";
                                                    //    ds1.Name = "FOUNDATION";
                                                    //    ds1.SetShape(new GeometryObject[] { solid });
                                                    //}
                                                }
                                            }
                                        }
                                    }

                                }
                            }

 

0 Likes
Message 4 of 5

zrodgersTSSSU
Advocate
Advocate

@jeremy_tammikI got the transform from the family instance however my solids still wont join. i would like to make the touching foundations all one solid so i can then use the vertical faces to make the formwork around them as a group. Any ideas why it isnt joining the solids?

 

//FORMWORK ONLY FOUNDATIONS
                        if ((BuiltInCategory)elem.Category.Id.IntegerValue == BuiltInCategory.OST_StructuralFoundation)
                        {
                            if (elem is FamilyInstance famInst)
                            {
                                Options opts = new Options();
                                
                                GeometryElement geoElem = elem.get_Geometry(opts);
                                GeometryElement originalGeometry = famInst.GetOriginalGeometry(opts);
                                FamilyInstance familyInstance = elem as FamilyInstance;
                                Transform t = familyInstance.GetTransform();
                                GeometryElement originalGeometryTransformed = originalGeometry.GetTransformed(t);

                                //for family elements that are cut/joined
                                if (famInst.HasModifiedGeometry())
                                {
                                    foreach (GeometryObject geoObj in originalGeometryTransformed)
                                    {

                                        Solid solid = geoObj as Solid;
                                        if (solid != null && 0 < solid.Faces.Size)
                                        {

                                            foundationSolids.Add(solid);
                                            ////TEST DIRECT SHAPE TO SEE IF ITS PICKING UP SOLIDS
                                            //DirectShape ds1 = null;
                                            //ds1 = DirectShape.CreateElement(doc, new ElementId(BuiltInCategory.OST_GenericModel));
                                            //ds1.ApplicationId = "Application id";
                                            //ds1.ApplicationDataId = "Geometry object id";
                                            //ds1.Name = "FOUNDATION";
                                            //ds1.SetShape(new GeometryObject[] { solid });
                                        }
                                    }

                                }
                                //for non-modified geometry
                                else
                                {
                                    foreach (GeometryObject geoObj in geoElem)
                                    {
                                        GeometryInstance geoInst = geoObj as GeometryInstance;
                                        if (null != geoInst)
                                        {
                                            GeometryElement instGeoElem = geoInst.GetInstanceGeometry();
                                            if (instGeoElem != null)
                                            {
                                                foreach (GeometryObject o in instGeoElem)
                                                {
                                                    Solid solid = o as Solid;
                                                    foundationSolids.Add(solid);
                                                    //double vol = solid.Volume;
                                                    //if (solid != null)
                                                    //{
                                                    //    //TEST DIRECT SHAPE TO SEE IF ITS PICKING UP SOLIDS
                                                    //    DirectShape ds1 = null;
                                                    //    ds1 = DirectShape.CreateElement(doc, new ElementId(BuiltInCategory.OST_GenericModel));
                                                    //    ds1.ApplicationId = "Application id";
                                                    //    ds1.ApplicationDataId = "Geometry object id";
                                                    //    ds1.Name = "FOUNDATION";
                                                    //    ds1.SetShape(new GeometryObject[] { solid });
                                                    //}
                                                }
                                            }
                                        }
                                    }

                                }
                            }

                            // Combine touching solids into a single solid
                            while (foundationSolids.Count > 0)
                            {
                                Solid currentSolid = foundationSolids[0];
                                foundationSolids.RemoveAt(0);

                                bool isJoined = false;

                                for (int i = foundationSolids.Count - 1; i >= 0; i--)
                                {
                                    Solid solidToCheck = foundationSolids[i];
                                    if (AreSolidsTouching(currentSolid, solidToCheck))
                                    {
                                        // Join the solids
                                        currentSolid = BooleanOperationsUtils.ExecuteBooleanOperation(currentSolid, solidToCheck, BooleanOperationsType.Union);
                                        foundationSolids.RemoveAt(i);
                                        isJoined = true;
                                    }
                                }

                                if (isJoined)
                                {
                                    //TEST DIRECT SHAPE TO SEE IF ITS PICKING UP SOLIDS
                                    DirectShape ds1 = null;
                                    ds1 = DirectShape.CreateElement(doc, new ElementId(BuiltInCategory.OST_GenericModel));
                                    ds1.ApplicationId = "Application id";
                                    ds1.ApplicationDataId = "Geometry object id";
                                    ds1.Name = "FOUNDATION";
                                    ds1.SetShape(new GeometryObject[] { currentSolid });

                                    joinedFndSolids.Add(currentSolid);
                                }
                                else
                                {
                                    joinedFndSolids.Add(currentSolid);
                                }
                            }

                            // Process the joined solids
                            foreach (Solid s in joinedFndSolids)
                            {
                                foreach (Face f in s.Faces)
                                {
                                    double norm = f.ComputeNormal(new UV(0.5, 0.5)).Z;
                                    if (norm == 0)
                                    {
                                        foundationFaces.Add(f);
                                    }
                                }
                            }




                        }

                    }

 

0 Likes
Message 5 of 5

zrodgersTSSSU
Advocate
Advocate
Accepted solution

Sorry its Friday and my brain is an hour behind the rest of the world. Please see below which works.

//FORMWORK ONLY FOUNDATIONS
                        if ((BuiltInCategory)elem.Category.Id.IntegerValue == BuiltInCategory.OST_StructuralFoundation)
                        {
                            if (elem is FamilyInstance famInst)
                            {
                                Options opts = new Options();
                                
                                GeometryElement geoElem = elem.get_Geometry(opts);
                                GeometryElement originalGeometry = famInst.GetOriginalGeometry(opts);
                                FamilyInstance familyInstance = elem as FamilyInstance;
                                Transform t = familyInstance.GetTransform();
                                GeometryElement originalGeometryTransformed = originalGeometry.GetTransformed(t);

                                //for family elements that are cut/joined
                                if (famInst.HasModifiedGeometry())
                                {
                                    foreach (GeometryObject geoObj in originalGeometryTransformed)
                                    {

                                        Solid solid = geoObj as Solid;
                                        if (solid != null && 0 < solid.Faces.Size)
                                        {

                                            foundationSolids.Add(solid);
                                            ////TEST DIRECT SHAPE TO SEE IF ITS PICKING UP SOLIDS
                                            //DirectShape ds1 = null;
                                            //ds1 = DirectShape.CreateElement(doc, new ElementId(BuiltInCategory.OST_GenericModel));
                                            //ds1.ApplicationId = "Application id";
                                            //ds1.ApplicationDataId = "Geometry object id";
                                            //ds1.Name = "FOUNDATION";
                                            //ds1.SetShape(new GeometryObject[] { solid });
                                        }
                                    }

                                }
                                //for non-modified geometry
                                else
                                {
                                    foreach (GeometryObject geoObj in geoElem)
                                    {
                                        GeometryInstance geoInst = geoObj as GeometryInstance;
                                        if (null != geoInst)
                                        {
                                            GeometryElement instGeoElem = geoInst.GetInstanceGeometry();
                                            if (instGeoElem != null)
                                            {
                                                foreach (GeometryObject o in instGeoElem)
                                                {
                                                    Solid solid = o as Solid;
                                                    foundationSolids.Add(solid);
                                                }
                                            }
                                        }
                                    }

                                }
                            }


                            // Combine touching solids into a single solid using a for loop
                            for (int i = 0; i < foundationSolids.Count; i++)
                            {
                                Solid currentSolid = foundationSolids[i];

                                if (currentSolid != null && currentSolid.Faces.Size > 0)
                                {
                                    for (int j = i + 1; j < foundationSolids.Count; j++)
                                    {
                                        Solid solidToCheck = foundationSolids[j];
                                        if (solidToCheck != null && solidToCheck.Faces.Size > 0 && AreSolidsTouching(currentSolid, solidToCheck))
                                        {
                                            // Join the solids
                                            currentSolid = BooleanOperationsUtils.ExecuteBooleanOperation(currentSolid, solidToCheck, BooleanOperationsType.Union);
                                            foundationSolids.RemoveAt(j);
                                            j--; // Adjust the index after removal
                                        }
                                    }

                                    // Add the joined or single solid to the joinedFndSolids list
                                    joinedFndSolids.Add(currentSolid);
                                }
                            }

                            // Process the joined solids
                            foreach (Solid s in joinedFndSolids)
                            {
                                foreach (Face f in s.Faces)
                                {
                                    double norm = f.ComputeNormal(new UV(0.5, 0.5)).Z;
                                    if (norm == 0)
                                    {
                                        foundationFaces.Add(f);
                                    }
                                }
                            }




                        }

                    }