<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Mathematical Translations in Revit API Forum</title>
    <link>https://forums.autodesk.com/t5/revit-api-forum/mathematical-translations/m-p/7590418#M54406</link>
    <description>&lt;P&gt;i do regulary use macro &lt;span class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;🙂&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;copy and paste should be enough.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;many thanks to Alexander for sharing his code.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Cheers,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;so-chong&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;/*
 * Created by SharpDevelop.
 * 
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */
using System;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI.Selection;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.DB.Structure;
using System.Collections.Generic;
using System.Linq;

namespace AutoWallsByCubes
{
    [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
    [Autodesk.Revit.DB.Macros.AddInId("AB4E399B-3B90-43ED-A8B5-E10C49F90340")]
	public partial class ThisApplication
	{
	    private void Module_Startup(object sender, EventArgs e)
	    {

	    }

	    private void Module_Shutdown(object sender, EventArgs e)
	    {

	    }

	    #region Revit Macros generated code
	    private void InternalStartup()
	    {
			this.Startup += new System.EventHandler(Module_Startup);
			this.Shutdown += new System.EventHandler(Module_Shutdown);
	    }
	    #endregion
	    public void AutomaticWallCreation()
	    {

            var uidoc = this.ActiveUIDocument;
            var doc = uidoc.Document;

            var cubes = FindCubes(doc);

            using (var transaction = new Transaction(doc, "create walls"))
            {
                transaction.Start();

                foreach (var cube in cubes)
                {
                    var countours = FindCountors(cube)
                        .SelectMany(x =&amp;gt; x);

                    var height = cube.LookupParameter("height").AsDouble();

                    foreach (var countour in countours)
                    {
                        var wall = CreateWall(cube, countour, height);

                        CreateDoor(wall);
                    }
                }

                transaction.Commit();
            }
            

        }

        private static Wall CreateWall(FamilyInstance cube, Curve curve, double height)
        {
            var doc = cube.Document;

            var wallTypeId = doc.GetDefaultElementTypeId(ElementTypeGroup.WallType);

            return Wall.Create(doc, curve.CreateReversed(), wallTypeId, cube.LevelId, height, 0, false, false);
        }

        private static void CreateDoor(Wall wall)
        {
            var locationCurve = (LocationCurve) wall.Location;

            var position = locationCurve.Curve.Evaluate(0.5, true);

            var document = wall.Document;

            var level = (Level)document.GetElement(wall.LevelId);

            var symbolId = document.GetDefaultFamilyTypeId(new ElementId(BuiltInCategory.OST_Doors));

            var symbol = (FamilySymbol)document.GetElement(symbolId);

            if (!symbol.IsActive)
                symbol.Activate();

            document.Create.NewFamilyInstance(position, symbol, wall, level, StructuralType.NonStructural);
        }

        private static IEnumerable&amp;lt;FamilyInstance&amp;gt; FindCubes(Document doc)
        {
            var collector = new FilteredElementCollector(doc);

            return collector
                .OfCategory(BuiltInCategory.OST_GenericModel)
                .OfClass(typeof (FamilyInstance))
                .OfType&amp;lt;FamilyInstance&amp;gt;()
                .Where(x =&amp;gt; x.Symbol.FamilyName == "cube");
        }

        private static IEnumerable&amp;lt;CurveLoop&amp;gt; FindCountors(FamilyInstance familyInstance)
        {
            return GetSolids(familyInstance)
                .SelectMany(x =&amp;gt; GetCountours(x, familyInstance));
        }

        private static IEnumerable&amp;lt;Solid&amp;gt; GetSolids(Element element)
        {
            var geometry = element
              .get_Geometry(new Options { ComputeReferences = true, IncludeNonVisibleObjects = true });

            if (geometry == null)
                return Enumerable.Empty&amp;lt;Solid&amp;gt;();

            return GetSolids(geometry)
                .Where(x =&amp;gt; x.Volume &amp;gt; 0);
        }

        private static IEnumerable&amp;lt;Solid&amp;gt; GetSolids(IEnumerable&amp;lt;GeometryObject&amp;gt; geometryElement)
        {
            foreach (var geometry in geometryElement)
            {
                var solid = geometry as Solid;
                if (solid != null)
                    yield return solid;

                var instance = geometry as GeometryInstance;
                if (instance != null)
                    foreach (var instanceSolid in GetSolids(instance.GetInstanceGeometry()))
                        yield return instanceSolid;

                var element = geometry as GeometryElement;
                if (element != null)
                    foreach (var elementSolid in GetSolids(element))
                        yield return elementSolid;
            }
        }

        private static IEnumerable&amp;lt;CurveLoop&amp;gt; GetCountours(Solid solid, Element element)
        {
            try
            {
                var plane = Plane.CreateByNormalAndOrigin(XYZ.BasisZ, element.get_BoundingBox(null).Min);

                var analyzer = ExtrusionAnalyzer.Create(solid, plane, XYZ.BasisZ);

                var face = analyzer.GetExtrusionBase();

                return face.GetEdgesAsCurveLoops();
            }
            catch (Autodesk.Revit.Exceptions.InvalidOperationException)
            {
                return Enumerable.Empty&amp;lt;CurveLoop&amp;gt;();
            }
        }
    }
}
		
	&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Fri, 01 Dec 2017 22:15:24 GMT</pubDate>
    <dc:creator>so-chong</dc:creator>
    <dc:date>2017-12-01T22:15:24Z</dc:date>
    <item>
      <title>Mathematical Translations</title>
      <link>https://forums.autodesk.com/t5/revit-api-forum/mathematical-translations/m-p/7580510#M54397</link>
      <description>&lt;P&gt;I am building an API that will create walls and doors inside a custom family that acts somewhat as an empty area if you will.&amp;nbsp; Since I cannot nest walls within the custom family, I have to create them via the API with (x,y,z) coordinates.&amp;nbsp; When the user places the custom cube (area) family, the walls will get built.&amp;nbsp; The issue is when the user selects a rotation that is not 0 deg, I do not know the translation of coordinates to assign to the wall start and end points.&amp;nbsp; I have completed all the trig to determine the angles and it will account for any angle the user selects.&amp;nbsp; How do I do the Mathematical translations to determine a formula which will help me determine the new start and end points of the walls?&amp;nbsp; I have attached documents to show how I determined the angles using the Bounding Box Mins and Max along with the insertion point.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;U&gt;The knowns I have are:&lt;/U&gt;&lt;/P&gt;&lt;P&gt;User selected Length from UI&lt;/P&gt;&lt;P&gt;User selected Width from UI&lt;/P&gt;&lt;P&gt;User selected Insertion Point&lt;/P&gt;&lt;P&gt;Bounding Box Max Point&lt;/P&gt;&lt;P&gt;Bounding Box Min Point&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Points pulled from this code:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;BoundingBoxXYZ modBox = currMod.get_BoundingBox(doc.ActiveView);&lt;BR /&gt;XYZ modBoxMin = modBox.Min;&lt;BR /&gt;XYZ modBoxMax = modBox.Max;&lt;BR /&gt;startPoint = GetFamLocation(currMod);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;//currMod is a custom family in the shape of a cube which I wish to build walls in but cannot due to not being able to nest system families.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;U&gt;Code used for trig:&lt;/U&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;string quadrant = "";&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;//------------QUADRANT I--------------//&lt;BR /&gt;if ((minXAbs &amp;lt;= 0) &amp;amp;&amp;amp; (minYAbs &amp;gt;= 0) &amp;amp;&amp;amp; (maxXAbs &amp;gt;= 0) &amp;amp;&amp;amp; (maxYAbs &amp;gt;= 0))&lt;BR /&gt;{&lt;BR /&gt;&amp;nbsp; &amp;nbsp; quadrant = "Q1";&lt;BR /&gt;&amp;nbsp; &amp;nbsp;&lt;BR /&gt;&amp;nbsp; &amp;nbsp; double ang01RAD = Math.Acos(Math.Abs(minXAbs) / massWidthDbl);&lt;BR /&gt;&amp;nbsp; &amp;nbsp; double ang01DEG = ang01RAD * (180 / Math.PI);&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;if (ang01RAD == 1)&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ang01DEG = 0;&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;modAngle = Math.Floor(90 - ang01DEG);&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;//------------QUADRANT II--------------//&lt;BR /&gt;else if ((minXAbs &amp;lt;= 0) &amp;amp;&amp;amp; (minYAbs &amp;lt;= 0) &amp;amp;&amp;amp; (maxXAbs &amp;lt;= 0) &amp;amp;&amp;amp; (maxYAbs &amp;gt;= 0))&lt;BR /&gt;{&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;quadrant = "Q2";&lt;BR /&gt;&lt;BR /&gt;&amp;nbsp; &amp;nbsp; double ang01RAD = Math.Acos(Math.Abs(maxYAbs) / massLengthDblUR);&lt;BR /&gt;&amp;nbsp; &amp;nbsp; double ang01DEG = ang01RAD * (180 / Math.PI);&lt;BR /&gt;&amp;nbsp; &amp;nbsp; modAngle = Math.Floor(90 + ang01DEG);&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;//------------QUADRANT III--------------//&lt;BR /&gt;else if ((minXAbs &amp;lt;= 0) &amp;amp;&amp;amp; (minYAbs &amp;lt;= 0) &amp;amp;&amp;amp; (maxXAbs &amp;gt;= 0) &amp;amp;&amp;amp; (maxYAbs &amp;lt;= 0))&lt;BR /&gt;{&lt;BR /&gt;&amp;nbsp; &amp;nbsp; quadrant = "Q3";&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp; double ang01RAD = Math.Atan(minXAbs / minYAbs);&lt;BR /&gt;&amp;nbsp; &amp;nbsp; double ang01DEG = ang01RAD * (180 / Math.PI);&lt;BR /&gt;&amp;nbsp; &amp;nbsp; double ang01Cos = Math.Cos(ang01RAD);&lt;BR /&gt;&amp;nbsp; &amp;nbsp; double hyp = Math.Abs(minYAbs) / ang01Cos;&lt;BR /&gt;&amp;nbsp; &amp;nbsp; double ang02DEG = 90 - ang01DEG;&lt;BR /&gt;&amp;nbsp; &amp;nbsp; double ang03DEG = 90 - ang02DEG;&lt;BR /&gt;&amp;nbsp; &amp;nbsp; double ang03RAD = ang03DEG * (Math.PI / 180);&lt;BR /&gt;&amp;nbsp; &amp;nbsp; double ang03Sin = Math.Sin(ang03RAD);&lt;BR /&gt;&amp;nbsp; &amp;nbsp; double ang04Helper = (hyp * ang03Sin) / massLengthDbl;&lt;BR /&gt;&amp;nbsp; &amp;nbsp; double ang04suppRAD = Math.Asin(Math.Abs(ang04Helper));&lt;BR /&gt;&amp;nbsp; &amp;nbsp; double ang04suppDEG = ang04suppRAD * (180 / Math.PI);&lt;BR /&gt;&amp;nbsp; &amp;nbsp; double ang04DEG = 180 - ang04suppDEG;&lt;BR /&gt;&amp;nbsp; &amp;nbsp; double ang05DEG = 180 - ang04DEG - ang01DEG;&lt;BR /&gt;&amp;nbsp; &amp;nbsp; double ang06DEG = 90 - ang05DEG - ang01DEG;&lt;BR /&gt;&amp;nbsp; &amp;nbsp; modAngle = Math.Floor(180 + ang06DEG);&lt;/P&gt;&lt;P&gt;}&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;//------------QUADRANT IV--------------//&lt;BR /&gt;else if ((minXAbs &amp;gt;= 0) &amp;amp;&amp;amp; (minYAbs &amp;lt;= 0) &amp;amp;&amp;amp; (maxXAbs &amp;gt;= 0) &amp;amp;&amp;amp; (maxYAbs &amp;gt;= 0))&lt;BR /&gt;{&lt;BR /&gt;&amp;nbsp; &amp;nbsp; if (quadrant != "Q1")&lt;BR /&gt;&amp;nbsp; &amp;nbsp; {&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;quadrant = "Q4";&lt;BR /&gt;&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; double ang01RAD = Math.Acos(Math.Abs(minYAbs) / massLengthDbl);&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; double ang01DEG = ang01RAD * (180 / Math.PI);&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; modAngle = Math.Floor(270 + Math.Round(ang01DEG));&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 28 Nov 2017 23:32:29 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/revit-api-forum/mathematical-translations/m-p/7580510#M54397</guid>
      <dc:creator>Anonymous</dc:creator>
      <dc:date>2017-11-28T23:32:29Z</dc:date>
    </item>
    <item>
      <title>Re: Mathematical Translations</title>
      <link>https://forums.autodesk.com/t5/revit-api-forum/mathematical-translations/m-p/7581163#M54398</link>
      <description>&lt;P&gt;&lt;SPAN&gt;Dear Elizabeth,&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Thank you for your interesting query.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;I looked at your attached 5-page PDF listing about 100 formulas, in my subjective impression.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Sorry, too much for me. Much too much.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;As far as I can tell from your verbal description, your problem is small and simple.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Very small and simple.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;I have a hunch that the solution is smaller and simpler still.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Are the cubes real cubes? I.e., all three axis lengths are equal?&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Are the walls you wish to create vertical?&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Do you wish to create walls along the four vertical faces of the cube, or where?&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Do you wish to add a floor and a ceiling?&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;I presume that an easy solution can be found that is valid for all quadrants, without distinction.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;I don't know what the purpose of your quadrants is.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;I hope this helps.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Second attempt at answering:&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;You have two points, p and q, representing the start and end point of the wall.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;The cube is inserted into the model, defining a transform T consisting of a rotation by an angle `a` and a translation by a vector `v`.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;To transform p and q by T, you could first rotate them both around the origin (or whatever axis point you prefer) by `a` and then translate then by `v` to wherever they are supposed to end up.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Does that get us any closer to understanding your question?&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Best regards,&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Jeremy&lt;/SPAN&gt;&lt;/P&gt;</description>
      <pubDate>Wed, 29 Nov 2017 08:13:45 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/revit-api-forum/mathematical-translations/m-p/7581163#M54398</guid>
      <dc:creator>jeremytammik</dc:creator>
      <dc:date>2017-11-29T08:13:45Z</dc:date>
    </item>
    <item>
      <title>Re: Mathematical Translations</title>
      <link>https://forums.autodesk.com/t5/revit-api-forum/mathematical-translations/m-p/7581337#M54399</link>
      <description>&lt;P&gt;Hi!&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Look at this code and attached revit file, may be it will be useful for you:&lt;/P&gt;&lt;PRE&gt;using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Structure;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.UI;

namespace AutoWallsByCubes
{
    [Transaction(TransactionMode.Manual)]
    public class CreateWallsAutomaticallyCommand : IExternalCommand
    {
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            var uiapp = commandData.Application;
            var uidoc = uiapp.ActiveUIDocument;
            var doc = uidoc.Document;

            var cubes = FindCubes(doc);

            using (var transaction = new Transaction(doc, "create walls"))
            {
                transaction.Start();

                foreach (var cube in cubes)
                {
                    var countours = FindCountors(cube)
                        .SelectMany(x =&amp;gt; x);

                    var height = cube.LookupParameter("height").AsDouble();

                    foreach (var countour in countours)
                    {
                        var wall = CreateWall(cube, countour, height);

                        CreateDoor(wall);
                    }
                }

                transaction.Commit();
            }
            
            return Result.Succeeded;
        }

        private static Wall CreateWall(FamilyInstance cube, Curve curve, double height)
        {
            var doc = cube.Document;

            var wallTypeId = doc.GetDefaultElementTypeId(ElementTypeGroup.WallType);

            return Wall.Create(doc, curve.CreateReversed(), wallTypeId, cube.LevelId, height, 0, false, false);
        }

        private static void CreateDoor(Wall wall)
        {
            var locationCurve = (LocationCurve) wall.Location;

            var position = locationCurve.Curve.Evaluate(0.5, true);

            var document = wall.Document;

            var level = (Level)document.GetElement(wall.LevelId);

            var symbolId = document.GetDefaultFamilyTypeId(new ElementId(BuiltInCategory.OST_Doors));

            var symbol = (FamilySymbol)document.GetElement(symbolId);

            if (!symbol.IsActive)
                symbol.Activate();

            document.Create.NewFamilyInstance(position, symbol, wall, level, StructuralType.NonStructural);
        }

        private static IEnumerable&amp;lt;FamilyInstance&amp;gt; FindCubes(Document doc)
        {
            var collector = new FilteredElementCollector(doc);

            return collector
                .OfCategory(BuiltInCategory.OST_GenericModel)
                .OfClass(typeof (FamilyInstance))
                .OfType&amp;lt;FamilyInstance&amp;gt;()
                .Where(x =&amp;gt; x.Symbol.FamilyName == "cube");
        }

        private static IEnumerable&amp;lt;CurveLoop&amp;gt; FindCountors(FamilyInstance familyInstance)
        {
            return GetSolids(familyInstance)
                .SelectMany(x =&amp;gt; GetCountours(x, familyInstance));
        }

        private static IEnumerable&amp;lt;Solid&amp;gt; GetSolids(Element element)
        {
            var geometry = element
              .get_Geometry(new Options { ComputeReferences = true, IncludeNonVisibleObjects = true });

            if (geometry == null)
                return Enumerable.Empty&amp;lt;Solid&amp;gt;();

            return GetSolids(geometry)
                .Where(x =&amp;gt; x.Volume &amp;gt; 0);
        }

        private static IEnumerable&amp;lt;Solid&amp;gt; GetSolids(IEnumerable&amp;lt;GeometryObject&amp;gt; geometryElement)
        {
            foreach (var geometry in geometryElement)
            {
                var solid = geometry as Solid;
                if (solid != null)
                    yield return solid;

                var instance = geometry as GeometryInstance;
                if (instance != null)
                    foreach (var instanceSolid in GetSolids(instance.GetInstanceGeometry()))
                        yield return instanceSolid;

                var element = geometry as GeometryElement;
                if (element != null)
                    foreach (var elementSolid in GetSolids(element))
                        yield return elementSolid;
            }
        }

        private static IEnumerable&amp;lt;CurveLoop&amp;gt; GetCountours(Solid solid, Element element)
        {
            try
            {
                var plane = Plane.CreateByNormalAndOrigin(XYZ.BasisZ, element.get_BoundingBox(null).Min);

                var analyzer = ExtrusionAnalyzer.Create(solid, plane, XYZ.BasisZ);

                var face = analyzer.GetExtrusionBase();

                return face.GetEdgesAsCurveLoops();
            }
            catch (InvalidOperationException)
            {
                return Enumerable.Empty&amp;lt;CurveLoop&amp;gt;();
            }
        }
    }
}&lt;/PRE&gt;&lt;P&gt;Before running command:&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="before.PNG" style="width: 705px;"&gt;&lt;img src="https://forums.autodesk.com/t5/image/serverpage/image-id/432302i55F9849701C3B9FA/image-size/large?v=v2&amp;amp;px=999" role="button" title="before.PNG" alt="before.PNG" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;After:&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="after.PNG" style="width: 705px;"&gt;&lt;img src="https://forums.autodesk.com/t5/image/serverpage/image-id/432303i367C8BF6BE0BD5D7/image-size/large?v=v2&amp;amp;px=999" role="button" title="after.PNG" alt="after.PNG" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;If not, explore Transform class (and its concept). You can get transform of your family instance using familyInstance.GetTotalTransform() method&lt;/P&gt;</description>
      <pubDate>Wed, 29 Nov 2017 09:13:23 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/revit-api-forum/mathematical-translations/m-p/7581337#M54399</guid>
      <dc:creator>aignatovich</dc:creator>
      <dc:date>2017-11-29T09:13:23Z</dc:date>
    </item>
    <item>
      <title>Re: Mathematical Translations</title>
      <link>https://forums.autodesk.com/t5/revit-api-forum/mathematical-translations/m-p/7582723#M54400</link>
      <description>&lt;P&gt;&lt;SPAN&gt;Jeremy,&lt;/SPAN&gt;&lt;/P&gt;&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;&lt;DIV&gt;Thank you for taking the time to help!&amp;nbsp; The cube is not necessarily a cube...it is rectangular in shape.&amp;nbsp; Items I wish to create that cannot be nested include walls, floors, and ceilings.&amp;nbsp; The walls which I want to create are both along the exterior faces of the rectangle and inside the area in which it consumes and they are all vertical.&amp;nbsp; Imagine this rectangle being a living quarters which would consist of bathroom, kitchen, laundry, and the walls that separate those areas.&amp;nbsp;&amp;nbsp;&lt;/DIV&gt;&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;&lt;DIV&gt;The use of quadrants was for me to determine which trig function I needed to determine the angle of rotation because I could only find the insertion point along with the BoundingBox Max and Min points.&amp;nbsp; I am unsure on how to do this in any other fashion, but would love to find a way which would eliminate the quadrants.&amp;nbsp; I tried to find faces so I could get their geometry information, but I kept getting an error as they always came back null.&amp;nbsp;&lt;/DIV&gt;&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;&lt;DIV&gt;On my commute home yesterday, I thought I could be completely overthinking this....which I tend to do often.&amp;nbsp; I was thinking I could build the walls in at 0 degrees and then rotate them all by the insertion point, which is the stationary point of the rectangle.&amp;nbsp; I believe this is a lot like what you are describing in the second portion.&amp;nbsp; However, I am still a little unclear on the translation vector you are describing.&lt;/DIV&gt;&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;&lt;DIV&gt;Elizabeth&lt;/DIV&gt;</description>
      <pubDate>Wed, 29 Nov 2017 16:30:38 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/revit-api-forum/mathematical-translations/m-p/7582723#M54400</guid>
      <dc:creator>Anonymous</dc:creator>
      <dc:date>2017-11-29T16:30:38Z</dc:date>
    </item>
    <item>
      <title>Re: Mathematical Translations</title>
      <link>https://forums.autodesk.com/t5/revit-api-forum/mathematical-translations/m-p/7582770#M54401</link>
      <description>&lt;P&gt;Aignatovich,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;Thank you for your time and input.&amp;nbsp; From the looks of your samples, this looks like it will work, but I need time to digest the code.&amp;nbsp; I will look it over!&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;Some of these concepts I have not used before such as Finding Contours.&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;Elizabeth&lt;/SPAN&gt;&lt;/P&gt;</description>
      <pubDate>Wed, 29 Nov 2017 16:44:42 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/revit-api-forum/mathematical-translations/m-p/7582770#M54401</guid>
      <dc:creator>Anonymous</dc:creator>
      <dc:date>2017-11-29T16:44:42Z</dc:date>
    </item>
    <item>
      <title>Re: Mathematical Translations</title>
      <link>https://forums.autodesk.com/t5/revit-api-forum/mathematical-translations/m-p/7585264#M54402</link>
      <description>&lt;P&gt;Dear Alexander,&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I love your code!&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I love your simple and efficient approach!&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I love your succinct generic helper functions!&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I promoted this to a post on The Building Coder to raise visibility:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;A href="http://thebuildingcoder.typepad.com/blog/2017/11/avoid-exorbitant-coordinates.html" target="_blank"&gt;http://thebuildingcoder.typepad.com/blog/2017/11/avoid-exorbitant-coordinates.html&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I hope many read your code and learn from it.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Thank you very much for sharing this!&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Cheers,&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Jeremy&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 30 Nov 2017 11:12:34 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/revit-api-forum/mathematical-translations/m-p/7585264#M54402</guid>
      <dc:creator>jeremytammik</dc:creator>
      <dc:date>2017-11-30T11:12:34Z</dc:date>
    </item>
    <item>
      <title>Re: Mathematical Translations</title>
      <link>https://forums.autodesk.com/t5/revit-api-forum/mathematical-translations/m-p/7585268#M54403</link>
      <description>&lt;P&gt;Dear Jeremy!&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thank you very much! &lt;img id="manhappy" class="emoticon emoticon-manhappy" src="https://forums.autodesk.com/i/smilies/16x16_man-happy.png" alt="Man Happy" title="Man Happy" /&gt;&lt;/P&gt;</description>
      <pubDate>Thu, 30 Nov 2017 11:16:13 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/revit-api-forum/mathematical-translations/m-p/7585268#M54403</guid>
      <dc:creator>aignatovich</dc:creator>
      <dc:date>2017-11-30T11:16:13Z</dc:date>
    </item>
    <item>
      <title>Re: Mathematical Translations</title>
      <link>https://forums.autodesk.com/t5/revit-api-forum/mathematical-translations/m-p/7589505#M54404</link>
      <description>&lt;P&gt;I'm trying to follow along with this example you had by creating a macro and I get this error when I try to build, Any idea why?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="error_automatic_wall_creation.png" style="width: 705px;"&gt;&lt;img src="https://forums.autodesk.com/t5/image/serverpage/image-id/433615i2346A775F1FADD23/image-size/large?v=v2&amp;amp;px=999" role="button" title="error_automatic_wall_creation.png" alt="error_automatic_wall_creation.png" /&gt;&lt;/span&gt;&lt;/P&gt;</description>
      <pubDate>Fri, 01 Dec 2017 16:25:34 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/revit-api-forum/mathematical-translations/m-p/7589505#M54404</guid>
      <dc:creator>Anonymous</dc:creator>
      <dc:date>2017-12-01T16:25:34Z</dc:date>
    </item>
    <item>
      <title>Re: Mathematical Translations</title>
      <link>https://forums.autodesk.com/t5/revit-api-forum/mathematical-translations/m-p/7589534#M54405</link>
      <description>&lt;P&gt;I do not generally use macros, so I cannot say for sure.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I would try to simply delete the offending line&amp;nbsp; &lt;span class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;🙂&lt;/span&gt;&lt;/P&gt;</description>
      <pubDate>Fri, 01 Dec 2017 16:37:04 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/revit-api-forum/mathematical-translations/m-p/7589534#M54405</guid>
      <dc:creator>jeremytammik</dc:creator>
      <dc:date>2017-12-01T16:37:04Z</dc:date>
    </item>
    <item>
      <title>Re: Mathematical Translations</title>
      <link>https://forums.autodesk.com/t5/revit-api-forum/mathematical-translations/m-p/7590418#M54406</link>
      <description>&lt;P&gt;i do regulary use macro &lt;span class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;🙂&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;copy and paste should be enough.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;many thanks to Alexander for sharing his code.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Cheers,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;so-chong&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;/*
 * Created by SharpDevelop.
 * 
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */
using System;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI.Selection;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.DB.Structure;
using System.Collections.Generic;
using System.Linq;

namespace AutoWallsByCubes
{
    [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
    [Autodesk.Revit.DB.Macros.AddInId("AB4E399B-3B90-43ED-A8B5-E10C49F90340")]
	public partial class ThisApplication
	{
	    private void Module_Startup(object sender, EventArgs e)
	    {

	    }

	    private void Module_Shutdown(object sender, EventArgs e)
	    {

	    }

	    #region Revit Macros generated code
	    private void InternalStartup()
	    {
			this.Startup += new System.EventHandler(Module_Startup);
			this.Shutdown += new System.EventHandler(Module_Shutdown);
	    }
	    #endregion
	    public void AutomaticWallCreation()
	    {

            var uidoc = this.ActiveUIDocument;
            var doc = uidoc.Document;

            var cubes = FindCubes(doc);

            using (var transaction = new Transaction(doc, "create walls"))
            {
                transaction.Start();

                foreach (var cube in cubes)
                {
                    var countours = FindCountors(cube)
                        .SelectMany(x =&amp;gt; x);

                    var height = cube.LookupParameter("height").AsDouble();

                    foreach (var countour in countours)
                    {
                        var wall = CreateWall(cube, countour, height);

                        CreateDoor(wall);
                    }
                }

                transaction.Commit();
            }
            

        }

        private static Wall CreateWall(FamilyInstance cube, Curve curve, double height)
        {
            var doc = cube.Document;

            var wallTypeId = doc.GetDefaultElementTypeId(ElementTypeGroup.WallType);

            return Wall.Create(doc, curve.CreateReversed(), wallTypeId, cube.LevelId, height, 0, false, false);
        }

        private static void CreateDoor(Wall wall)
        {
            var locationCurve = (LocationCurve) wall.Location;

            var position = locationCurve.Curve.Evaluate(0.5, true);

            var document = wall.Document;

            var level = (Level)document.GetElement(wall.LevelId);

            var symbolId = document.GetDefaultFamilyTypeId(new ElementId(BuiltInCategory.OST_Doors));

            var symbol = (FamilySymbol)document.GetElement(symbolId);

            if (!symbol.IsActive)
                symbol.Activate();

            document.Create.NewFamilyInstance(position, symbol, wall, level, StructuralType.NonStructural);
        }

        private static IEnumerable&amp;lt;FamilyInstance&amp;gt; FindCubes(Document doc)
        {
            var collector = new FilteredElementCollector(doc);

            return collector
                .OfCategory(BuiltInCategory.OST_GenericModel)
                .OfClass(typeof (FamilyInstance))
                .OfType&amp;lt;FamilyInstance&amp;gt;()
                .Where(x =&amp;gt; x.Symbol.FamilyName == "cube");
        }

        private static IEnumerable&amp;lt;CurveLoop&amp;gt; FindCountors(FamilyInstance familyInstance)
        {
            return GetSolids(familyInstance)
                .SelectMany(x =&amp;gt; GetCountours(x, familyInstance));
        }

        private static IEnumerable&amp;lt;Solid&amp;gt; GetSolids(Element element)
        {
            var geometry = element
              .get_Geometry(new Options { ComputeReferences = true, IncludeNonVisibleObjects = true });

            if (geometry == null)
                return Enumerable.Empty&amp;lt;Solid&amp;gt;();

            return GetSolids(geometry)
                .Where(x =&amp;gt; x.Volume &amp;gt; 0);
        }

        private static IEnumerable&amp;lt;Solid&amp;gt; GetSolids(IEnumerable&amp;lt;GeometryObject&amp;gt; geometryElement)
        {
            foreach (var geometry in geometryElement)
            {
                var solid = geometry as Solid;
                if (solid != null)
                    yield return solid;

                var instance = geometry as GeometryInstance;
                if (instance != null)
                    foreach (var instanceSolid in GetSolids(instance.GetInstanceGeometry()))
                        yield return instanceSolid;

                var element = geometry as GeometryElement;
                if (element != null)
                    foreach (var elementSolid in GetSolids(element))
                        yield return elementSolid;
            }
        }

        private static IEnumerable&amp;lt;CurveLoop&amp;gt; GetCountours(Solid solid, Element element)
        {
            try
            {
                var plane = Plane.CreateByNormalAndOrigin(XYZ.BasisZ, element.get_BoundingBox(null).Min);

                var analyzer = ExtrusionAnalyzer.Create(solid, plane, XYZ.BasisZ);

                var face = analyzer.GetExtrusionBase();

                return face.GetEdgesAsCurveLoops();
            }
            catch (Autodesk.Revit.Exceptions.InvalidOperationException)
            {
                return Enumerable.Empty&amp;lt;CurveLoop&amp;gt;();
            }
        }
    }
}
		
	&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 01 Dec 2017 22:15:24 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/revit-api-forum/mathematical-translations/m-p/7590418#M54406</guid>
      <dc:creator>so-chong</dc:creator>
      <dc:date>2017-12-01T22:15:24Z</dc:date>
    </item>
    <item>
      <title>Re: Mathematical Translations</title>
      <link>https://forums.autodesk.com/t5/revit-api-forum/mathematical-translations/m-p/7594398#M54407</link>
      <description>&lt;P&gt;Thanks, very much appreciated!&lt;/P&gt;</description>
      <pubDate>Mon, 04 Dec 2017 15:53:35 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/revit-api-forum/mathematical-translations/m-p/7594398#M54407</guid>
      <dc:creator>Anonymous</dc:creator>
      <dc:date>2017-12-04T15:53:35Z</dc:date>
    </item>
  </channel>
</rss>

