public bool CreateElevationByWall()
        {
            bool result = false;

            try
            {
                ElevationMarker marker         = null;
                XYZ             markerLocation = null;
                Dictionary <int, ElevationViewProperties> elevationViews = new Dictionary <int, ElevationViewProperties>();
                ApplyTemplateSettings();

                using (Transaction trans = new Transaction(m_doc, "Elevation Creator"))
                {
                    trans.Start();
                    try
                    {
                        BoundingBoxXYZ bbBox = m_room.get_BoundingBox(null);
                        markerLocation = new XYZ(pickPoint.X, pickPoint.Y, bbBox.Min.Z);
                        if (m_room.Document.IsLinked)
                        {
                            var documents = from doc in linkedDocuments.Values where doc.DocumentTitle == m_room.Document.Title select doc;
                            if (documents.Count() > 0)
                            {
                                LinkedInstanceProperties lip = documents.First();
                                roomLink       = lip;
                                markerLocation = lip.TransformValue.OfPoint(markerLocation);
                            }
                        }

                        marker = ElevationMarker.CreateElevationMarker(m_doc, m_viewFamilyTypeId, markerLocation, toolSettings.CustomScale);
                        trans.Commit();

                        if (null != marker)
                        {
                            string prefix           = toolSettings.PrefixText;
                            string intermediateText = GetRoomParameterValue(m_room, toolSettings.IntermediateText);
                            int    elevationIndex   = GetElevationMarkIndex();
                            string suffix           = GetRoomParameterValue(m_room, toolSettings.SuffixText);

                            int viewCount = marker.MaximumViewCount < suffix.Length ? marker.MaximumViewCount : suffix.Length;

                            double rotationalAngle = 0;
                            Dictionary <int, string> indexLabels = GetMarkerLabel(markerLocation, out rotationalAngle);
                            bool firstView = true;
                            foreach (int index in indexLabels.Keys)
                            {
                                if (index < marker.MaximumViewCount)
                                {
                                    trans.Start();
                                    ViewSection viewElevation = marker.CreateElevation(m_doc, m_viewPlan.Id, index);
                                    viewElevation.Name = GetViewName(prefix, intermediateText, elevationIndex, indexLabels[index], suffix);
                                    if (toolSettings.ViewTemplateId != -1)
                                    {
                                        viewElevation.ViewTemplateId = new ElementId(toolSettings.ViewTemplateId);
                                    }

                                    Parameter param = viewElevation.LookupParameter("Title on Sheet");
                                    if (null != param)
                                    {
                                        param.Set(m_room.Name);
                                    }

                                    trans.Commit();

                                    if (firstView && null != viewElevation)
                                    {
                                        trans.Start();
                                        try
                                        {
                                            bool rotated = RotateMarker(marker, markerLocation, rotationalAngle);
                                            firstView = false;
                                            trans.Commit();
                                        }
                                        catch (Exception ex)
                                        {
                                            trans.RollBack();
                                            MessageBox.Show("Failed to rotate the elevation marker.\n" + ex.Message, "Elevation Creator : RotateMarker", MessageBoxButton.OK, MessageBoxImage.Warning);
                                        }
                                    }

                                    ElevationViewProperties viewProperties = new ElevationViewProperties(viewElevation);
                                    viewProperties.WallId = m_wall.Id.IntegerValue;
                                    if (!elevationViews.ContainsKey(viewProperties.ViewId))
                                    {
                                        elevationViews.Add(viewProperties.ViewId, viewProperties);
                                    }
                                }
                            }

                            if (elevationViews.Count > 0 && !roomProperties.ElevationViews.ContainsKey(marker.Id.IntegerValue))
                            {
                                roomProperties.ElevationViews.Add(marker.Id.IntegerValue, elevationViews);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        trans.RollBack();
                        MessageBox.Show("Failed to create an elevation view.\n" + ex.Message, "Create Elevation View", MessageBoxButton.OK, MessageBoxImage.Warning);
                        return(false);
                    }
                }

                if (null != marker && null != markerLocation)
                {
                    if (ModifyCropBox(roomProperties, marker.Id.IntegerValue))
                    {
                        if (ElevationCreatorDataStorageUtil.StoreRoomElevationProperties(m_doc, roomProperties))
                        {
                            //update extensible storage
                            result = true;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Failed to create an elevation view.\nRoom Name: " + m_room.Name + "\nWall Name: " + m_wall.Name + "\n" + ex.Message, "", MessageBoxButton.OK, MessageBoxImage.Warning);
            }
            return(result);
        }
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            #region//Utils
            StringBuilder       sb        = new StringBuilder();
            Collector           collector = new Collector();
            LengthUnitConverter converter = new LengthUnitConverter();
            #endregion

            #region//Application context
            UIDocument uidoc = commandData.Application.ActiveUIDocument;
            Document   doc   = uidoc.Document;
            #endregion

            #region//Check if current project is family
            if (doc.IsFamilyDocument)
            {
                Message.Display("Can't use command in family document", WindowType.Warning);
                return(Result.Cancelled);
            }
            #endregion

            #region//Select elements
            List <Element> genericModelList         = collector.GetGenericModels(doc);
            List <Element> List_GenericModels       = new List <Element>();
            List <string>  List_GenericModelStrings = new List <string>();
            FamilyInstance familyInstance           = null;

            foreach (Element genericModel in genericModelList)
            {
                familyInstance = doc.GetElement(genericModel.Id) as FamilyInstance;
                if (familyInstance.SuperComponent == null)
                {
                    if (List_GenericModelStrings.Contains(genericModel.Name))
                    {
                    }
                    else
                    {
                        List_GenericModels.Add(genericModel);
                        List_GenericModelStrings.Add(genericModel.Name);
                    }
                }
            }
            #endregion

            #region//Check if list of generic models is empty
            if (List_GenericModels.Count == 0)
            {
                Message.Display("There aren't any generic models in the project", WindowType.Warning);
                return(Result.Cancelled);
            }
            #endregion

            #region//Execute task for each generic model
            foreach (Element genericModel in List_GenericModels)
            {
                FamilyInstance genericModelFamily = doc.GetElement(genericModel.Id) as FamilyInstance;
                FamilySymbol   genericModelSymbol = genericModelFamily.Symbol;

                #region //Get type parameters of element
                string MDK_merk = genericModelSymbol.LookupParameter("MDK_merk").AsString();
                #endregion

                #region //Get nested family
                FamilyInstance nestedFamily     = null;
                string         nestedFamilyName = "Profiel_1";

                List <double>         nestedFamilyOriginZ = new List <double>();
                List <FamilyInstance> nestedFamilies      = new List <FamilyInstance>();

                FamilyInstance familyContainer = null;
                LocationCurve  curveContainer  = null;
                Line           lineContainer   = null;

                ICollection <ElementId> subComponentIds = genericModelFamily.GetSubComponentIds();
                foreach (ElementId id in subComponentIds)
                {
                    if (doc.GetElement(id).Name == nestedFamilyName)
                    {
                        nestedFamilies.Add(doc.GetElement(id) as FamilyInstance);
                        familyContainer = doc.GetElement(id) as FamilyInstance;
                        curveContainer  = familyContainer.Location as LocationCurve;
                        lineContainer   = curveContainer.Curve as Line;
                        nestedFamilyOriginZ.Add(lineContainer.Origin.Z);
                    }
                }

                double minValue = int.MaxValue;
                int    minIndex;
                int    index = -1;

                foreach (double num in nestedFamilyOriginZ)
                {
                    index++;
                    if (num <= minValue)
                    {
                        minValue = num;
                        minIndex = index;
                    }
                }

                nestedFamily = nestedFamilies[index];

                if (nestedFamily == null)
                {
                    Message.Display("There isn't a nested family in the element with the specified name.", WindowType.Error);
                    return(Result.Cancelled);
                }
                #endregion

                #region//Get direction of family
                LocationCurve locationCurve = nestedFamily.Location as LocationCurve;
                Line          locationLine  = locationCurve.Curve as Line;
                XYZ           dir           = locationLine.Direction.Normalize();;
                #endregion

                #region//Create Boundingbox
                XYZ lineStart      = locationLine.GetEndPoint(0);
                XYZ lineEnd        = locationLine.GetEndPoint(1);
                XYZ lineDifference = lineEnd - lineStart;

                BoundingBoxXYZ genicModelbb = genericModel.get_BoundingBox(null);
                double         minZ         = genicModelbb.Min.Z;
                double         maxZ         = genicModelbb.Max.Z;

                double width     = lineDifference.GetLength();
                double height    = maxZ - minZ;
                double thickness = converter.ConvertToFeet(500);
                double offset    = converter.ConvertToFeet(500);

                XYZ min = new XYZ(-width - converter.ConvertToFeet(1000), minZ - offset, -offset);
                XYZ max = new XYZ(width, maxZ + offset, +offset);

                XYZ midpoint = lineStart + 0.5 * lineDifference;
                XYZ up       = XYZ.BasisZ;
                XYZ viewDir  = dir.CrossProduct(up);

                Transform t = Transform.Identity;
                t.Origin = midpoint;
                t.BasisX = dir;
                t.BasisY = up;
                t.BasisZ = viewDir;

                BoundingBoxXYZ boundingBox = new BoundingBoxXYZ();
                boundingBox.Transform = t;
                boundingBox.Min       = min;
                boundingBox.Max       = max;
                #endregion

                #region//Get viewFamilyType
                ViewFamilyType viewFamily = collector.GetViewFamilyType(doc, ViewFamily.Section).FirstOrDefault();
                #endregion

                #region //Create Section
                using (Transaction tx = new Transaction(doc))
                {
                    tx.Start("Create Section");

                    ViewSection section = ViewSection.CreateSection(doc, viewFamily.Id, boundingBox);
                    section.Name           = genericModel.Name;
                    section.Scale          = 50;
                    section.CropBoxVisible = false;
                    section.get_Parameter(BuiltInParameter.SECTION_COARSER_SCALE_PULLDOWN_METRIC).Set(1);
                    section.LookupParameter("Subdiscipline").Set("LEGEND");

                    tx.Commit();
                }
                #endregion
            }
            #endregion

            #region//Get all section views
            List <View> sectionViewList   = collector.GetViews(doc, ViewType.Section);
            List <View> List_SectionViews = new List <View>();

            foreach (View sectionView in sectionViewList)
            {
                if (sectionView.Name.Contains("Kozijn"))
                {
                    List_SectionViews.Add(sectionView);
                }
            }
            #endregion

            #region//Execute task for each sectionView
            foreach (View sectionView in List_SectionViews)
            {
                #region//Get DimensionType
                DimensionType genericModelDimension = collector.GetLinearDimensionTypeByName(doc, "hoofdmaatvoering");
                DimensionType nestedFamilyDimension = collector.GetLinearDimensionTypeByName(doc, "stelkozijn");
                #endregion

                #region//Get directions for dimensions
                XYZ widthDirection  = sectionView.RightDirection.Normalize();
                XYZ heigthDirection = new XYZ(0, 0, 1);
                #endregion

                #region//Select elements
                List <Element> genericModelInViewList   = collector.GetGenericModels(doc, sectionView.Id);
                List <Element> List_GenericModelsInView = new List <Element>();
                FamilyInstance familyInstanceInView     = null;

                foreach (Element genericModel in genericModelInViewList)
                {
                    familyInstanceInView = doc.GetElement(genericModel.Id) as FamilyInstance;
                    if (familyInstanceInView.SuperComponent == null)
                    {
                        List_GenericModelsInView.Add(genericModel);
                    }
                }
                #endregion

                #region//Execute task for each generic model
                foreach (Element genericModel in List_GenericModelsInView)
                {
                    FamilyInstance genericModelFamily = doc.GetElement(genericModel.Id) as FamilyInstance;
                    FamilySymbol   genericModelSymbol = genericModelFamily.Symbol;

                    #region//Get nested family 1
                    string         nestedFamilyName1 = "31_MDK_GM_stelkozijn_lijn";
                    FamilyInstance nestedFamily1     = null;

                    ICollection <ElementId> subComponentIds1 = genericModelFamily.GetSubComponentIds();
                    foreach (ElementId id in subComponentIds1)
                    {
                        if (doc.GetElement(id).Name == nestedFamilyName1)
                        {
                            nestedFamily1 = doc.GetElement(id) as FamilyInstance;
                        }
                    }
                    #endregion

                    #region//Get nested family 2
                    FamilyInstance nestedFamily2     = null;
                    string         nestedFamilyName2 = "Profiel_1";

                    List <double>         nestedFamilyOriginZ = new List <double>();
                    List <FamilyInstance> nestedFamilies      = new List <FamilyInstance>();

                    FamilyInstance familyContainer = null;
                    LocationCurve  curveContainer  = null;
                    Line           lineContainer   = null;

                    ICollection <ElementId> subComponentIds2 = genericModelFamily.GetSubComponentIds();
                    foreach (ElementId id in subComponentIds2)
                    {
                        if (doc.GetElement(id).Name == nestedFamilyName2)
                        {
                            nestedFamilies.Add(doc.GetElement(id) as FamilyInstance);
                            familyContainer = doc.GetElement(id) as FamilyInstance;
                            curveContainer  = familyContainer.Location as LocationCurve;
                            lineContainer   = curveContainer.Curve as Line;
                            nestedFamilyOriginZ.Add(lineContainer.Origin.Z);
                        }
                    }

                    double minValue = int.MaxValue;
                    int    minIndex;
                    int    index = -1;

                    foreach (double num in nestedFamilyOriginZ)
                    {
                        index++;
                        if (num <= minValue)
                        {
                            minValue = num;
                            minIndex = index;
                        }
                    }

                    nestedFamily2 = nestedFamilies[index];

                    if (nestedFamily2 == null)
                    {
                        Message.Display("There isn't a nested family in the element with the specified name.", WindowType.Error);
                        return(Result.Cancelled);
                    }
                    #endregion

                    #region//Get type parameters of element
                    double MDK_breedte = genericModelSymbol.LookupParameter("MDK_breedte").AsDouble();
                    #endregion

                    #region//Get instance parameters of element
                    double MDK_offset_vooraanzicht = genericModelFamily.LookupParameter("MDK_offset_vooraanzicht").AsDouble();
                    #endregion

                    #region//Get direction of family
                    LocationCurve locationCurve = nestedFamily2.Location as LocationCurve;
                    Line          locationLine  = locationCurve.Curve as Line;
                    XYZ           dir           = locationLine.Direction.Normalize();;
                    #endregion

                    #region//Check if generic model is in same direction as view
                    double genericModelAngle = Math.Round(Math.Atan2(dir.Y, dir.X) * (180 / Math.PI), 5);
                    double activeViewAngle   = Math.Round(Math.Atan2(widthDirection.Y, widthDirection.X) * (180 / Math.PI), 5);
                    if (genericModelAngle <= 0)
                    {
                        genericModelAngle = genericModelAngle + 180;
                    }
                    else
                    {
                        genericModelAngle = genericModelAngle - 180;
                    }

                    if (genericModelAngle != activeViewAngle)
                    {
                        Message.Display("The generic model isn't parallel to the active view.", WindowType.Error);
                        return(Result.Cancelled);
                    }
                    #endregion

                    #region//Get locationpoint of selected element
                    LocationPoint location      = genericModelFamily.Location as LocationPoint;
                    XYZ           locationpoint = location.Point;
                    #endregion

                    #region// Get references which refer to the reference planes in the family
                    ReferenceArray genericModelHeightref = new ReferenceArray();
                    ReferenceArray genericModelWidthref  = new ReferenceArray();
                    ReferenceArray nestedFamilyHeightref = new ReferenceArray();
                    ReferenceArray nestedFamilyWidthref  = new ReferenceArray();

                    foreach (var e in genericModelFamily.GetReferences(FamilyInstanceReferenceType.Top))
                    {
                        genericModelHeightref.Append(e);
                    }

                    foreach (var e in genericModelFamily.GetReferences(FamilyInstanceReferenceType.Bottom))
                    {
                        genericModelHeightref.Append(e);
                    }

                    foreach (var e in genericModelFamily.GetReferences(FamilyInstanceReferenceType.StrongReference))
                    {
                        genericModelWidthref.Append(e);
                    }

                    foreach (var e in nestedFamily1.GetReferences(FamilyInstanceReferenceType.StrongReference))
                    {
                        nestedFamilyWidthref.Append(e);
                    }

                    foreach (var e in nestedFamily1.GetReferences(FamilyInstanceReferenceType.Top))
                    {
                        nestedFamilyHeightref.Append(e);
                    }

                    foreach (var e in nestedFamily1.GetReferences(FamilyInstanceReferenceType.Bottom))
                    {
                        nestedFamilyHeightref.Append(e);
                    }
                    #endregion

                    #region//Create endpoints for line creation
                    XYZ genericModelHeight = GetDistance(locationpoint, widthDirection, MDK_breedte, 1000);
                    XYZ genericModelWidth  = new XYZ(locationpoint.X, locationpoint.Y, locationpoint.Z + MDK_offset_vooraanzicht - converter.ConvertToFeet(1000));
                    XYZ nestedFamilyHeight = GetDistance(locationpoint, widthDirection, MDK_breedte, 500);
                    XYZ nestedFamilyWidth  = new XYZ(locationpoint.X, locationpoint.Y, locationpoint.Z + MDK_offset_vooraanzicht - converter.ConvertToFeet(500));
                    #endregion

                    #region//Create line for dimension
                    Line genericModelHeightLine = Line.CreateBound(genericModelHeight, genericModelHeight + heigthDirection * 100);
                    Line genericModelWidthLine  = Line.CreateBound(genericModelWidth, genericModelWidth + widthDirection * 100);
                    Line nestedFamilyHeightLine = Line.CreateBound(nestedFamilyHeight, nestedFamilyHeight + heigthDirection * 100);
                    Line nestedFamilyWidthLine  = Line.CreateBound(nestedFamilyWidth, nestedFamilyWidth + widthDirection * 100);
                    #endregion

                    #region//Create Dimensions
                    using (Transaction tx = new Transaction(doc))
                    {
                        tx.Start("Create Dimensions");

                        #region//Create and set workplane to place dimensions on
                        Plane       plane       = Plane.CreateByNormalAndOrigin(sectionView.ViewDirection, sectionView.Origin);
                        SketchPlane sketchPlane = SketchPlane.Create(doc, plane);
                        sectionView.SketchPlane = sketchPlane;
                        #endregion

                        #region//Create Dimensions
                        doc.Create.NewDimension(sectionView, genericModelHeightLine, genericModelHeightref, genericModelDimension);
                        doc.Create.NewDimension(sectionView, genericModelWidthLine, genericModelWidthref, genericModelDimension);
                        doc.Create.NewDimension(sectionView, nestedFamilyHeightLine, nestedFamilyHeightref, nestedFamilyDimension);
                        doc.Create.NewDimension(sectionView, nestedFamilyWidthLine, nestedFamilyWidthref, nestedFamilyDimension);
                        #endregion

                        tx.Commit();
                    }
                    #endregion
                }
                #endregion
            }
            #endregion
            return(Result.Succeeded);
        }
        public bool CreateElevationByList()
        {
            bool result = false;

            try
            {
                ElevationMarker marker         = null;
                XYZ             markerLocation = null;


                ApplyTemplateSettings();

                using (Transaction trans = new Transaction(m_doc, "Create Elevation Marker"))
                {
                    trans.Start();
                    try
                    {
                        BoundingBoxXYZ bbBox = m_room.get_BoundingBox(null);
                        markerLocation = new XYZ((bbBox.Max.X + bbBox.Min.X) / 2, (bbBox.Max.Y + bbBox.Min.Y) / 2, bbBox.Min.Z);

                        //LocationPoint locationPoint = m_room.Location as LocationPoint;
                        //markerLocation = locationPoint.Point;
                        if (m_room.Document.IsLinked)
                        {
                            var documents = from doc in linkedDocuments.Values where doc.DocumentTitle == m_room.Document.Title select doc;
                            if (documents.Any())
                            {
                                LinkedInstanceProperties lip = documents.First();
                                roomLink       = lip;
                                markerLocation = lip.TransformValue.OfPoint(markerLocation);
                            }
                        }

                        marker = ElevationMarker.CreateElevationMarker(m_doc, m_viewFamilyTypeId, markerLocation, toolSettings.CustomScale);
                        trans.Commit();
                    }
                    catch (Exception ex)
                    {
                        trans.RollBack();
                        LogMessageBuilder.AddLogMessage(roomProperties.RoomNumber + " - " + roomProperties.RoomName + " : failed to create an elevation marker.");
                        LogMessageBuilder.AddLogMessage(ex.Message);
                        //MessageBox.Show("Failed to create an elevation marker.\n" + ex.Message, "Elevation Creator: Create Elevation Marker", MessageBoxButton.OK, MessageBoxImage.Warning);
                    }
                }

                if (null != marker)
                {
                    using (Transaction trans = new Transaction(m_doc, "Create Elevation Views"))
                    {
                        trans.Start();
                        try
                        {
                            string prefix           = toolSettings.PrefixText;
                            string intermediateText = GetRoomParameterValue(m_room, toolSettings.IntermediateText);
                            int    elevationIndex   = GetElevationMarkIndex();
                            string suffix           = GetRoomParameterValue(m_room, toolSettings.SuffixText);

                            int viewCount = marker.MaximumViewCount < 4 ? marker.MaximumViewCount : 4;

                            Dictionary <int, Dictionary <int, ElevationViewProperties> > elevationDictionary = new Dictionary <int, Dictionary <int, ElevationViewProperties> >();
                            Dictionary <int, ElevationViewProperties> elevationViews = new Dictionary <int, ElevationViewProperties>();

                            for (int i = 0; i < viewCount; i++)
                            {
                                string indexText = "";
                                if (i == 0 && toolSettings.DIsSelected)
                                {
                                    indexText = "D";
                                }
                                else if (i == 1 && toolSettings.AIsSelected)
                                {
                                    indexText = "A";
                                }
                                else if (i == 2 && toolSettings.BIsSelected)
                                {
                                    indexText = "B";
                                }
                                else if (i == 3 && toolSettings.CIsSelected)
                                {
                                    indexText = "C";
                                }
                                else
                                {
                                    continue;
                                }

                                ViewSection viewElevation = marker.CreateElevation(m_doc, m_viewPlan.Id, i);
                                viewElevation.Name = GetViewName(prefix, intermediateText, elevationIndex, indexText, suffix);
                                if (toolSettings.ViewTemplateId != -1)
                                {
                                    viewElevation.ViewTemplateId = new ElementId(toolSettings.ViewTemplateId);
                                }

                                Parameter param = viewElevation.LookupParameter("Title on Sheet");

                                if (null != param)
                                {
                                    param.Set(m_room.Name);
                                }

                                ElevationViewProperties viewProperties = new ElevationViewProperties(viewElevation);
                                if (!elevationViews.ContainsKey(viewProperties.ViewId))
                                {
                                    elevationViews.Add(viewProperties.ViewId, viewProperties);
                                }
                            }

                            if (elevationViews.Count > 0 && !roomProperties.ElevationViews.ContainsKey(marker.Id.IntegerValue))
                            {
                                roomProperties.KeyMarkId = marker.Id.IntegerValue;
                                roomProperties.ElevationViews.Add(marker.Id.IntegerValue, elevationViews);
                            }

                            trans.Commit();
                        }
                        catch (Exception ex)
                        {
                            trans.RollBack();
                            LogMessageBuilder.AddLogMessage(roomProperties.RoomNumber + " - " + roomProperties.RoomName + " : failed to create elevation views.");
                            LogMessageBuilder.AddLogMessage(ex.Message);
                            //MessageBox.Show("Failed to create elevation views.\n" + ex.Message, "Elevation Creator: Create Elevation Views", MessageBoxButton.OK, MessageBoxImage.Warning);
                        }
                    }
                }

                if (null != marker && null != markerLocation)
                {
                    if (ModifyCropBox(roomProperties, marker.Id.IntegerValue))
                    {
                        if (ElevationCreatorDataStorageUtil.StoreRoomElevationProperties(m_doc, roomProperties))
                        {
                            //update extensible storage
                            result = true;
                        }
                    }
                }
                result = true;
            }
            catch (Exception ex)
            {
                LogMessageBuilder.AddLogMessage(roomProperties.RoomNumber + " - " + roomProperties.RoomName + " : failed to create elevations by room lists.\n" + ex.Message);
                //MessageBox.Show("Failed to create elevation by room lists.\n"+ex.Message, "Elevation Creator: CreateElevationByList", MessageBoxButton.OK, MessageBoxImage.Warning);
            }
            return(result);
        }