예제 #1
0
        /// <summary>
        /// Mutate the name of the level
        /// </summary>
        /// <param name="name"> the name we want to set the level to have</param>
        /// <param name="oldname"> the oldname we tried to set this level to in the past,
        /// we retrieve this from trace</param>
        private void InternalSetName(string oldname, string name)
        {
            if (String.IsNullOrEmpty(name) ||
                string.CompareOrdinal(InternalLevel.Name, name) == 0 ||
                string.CompareOrdinal(oldname, name) == 0)
            {
                return;
            }
            //make a copy of the string
            var originalInputName = name;
            //Check to see whether there is an existing level with the same name
            var levels = ElementQueries.GetAllLevels();

            while (levels.Any(x => string.CompareOrdinal(x.Name, name) == 0))
            {
                //Update the level name
                Revit.Elements.InternalUtilities.ElementUtils.UpdateLevelName(ref name);
            }

            TransactionManager.Instance.EnsureInTransaction(Document);
            this.InternalLevel.Name = name;
            var updatedTraceData = new LevelTraceData(this, originalInputName);

            ElementBinder.SetRawDataForTrace(updatedTraceData);
            TransactionManager.Instance.TransactionTaskDone();
        }
예제 #2
0
        /// <summary>
        /// Initialize a DirectShape element
        /// </summary>
        private void InitDirectShape(DesignScriptEntity shapeReference,
                                     string shapeName,
                                     Category category,
                                     Material material)
        {
            //Phase 1 - Check to see if a DirectShape exists in trace and should be rebound
            var oldShape =
                ElementBinder.GetElementAndTraceData <Autodesk.Revit.DB.DirectShape, DirectShapeState>(Document);

            //There was a oldDirectShape, rebind to that
            if (oldShape != null)
            {
                //set the directshape element
                this.InternalSetDirectShape(oldShape.Item1);

                //if the cateogryID has changed, we cannot continue to rebind and instead
                //will make a new directShape
                if (category.Id == this.InternalElement.Category.Id.IntegerValue)
                {
                    //set the shape geometry of the directshape, this method passes in the actual input geo
                    //and checks the directShapeState object at the elementId key in the input geo tags dictionary.
                    //this check is used to determine if the geometry should be updated, this is done by checking
                    //the sync guid in the DirectShapeState (a guid that is generated when geometry changes on
                    //the revit element.
                    //we also check the material, if it's different than the currently assigned material
                    //then we need to rebuild the geo so that a new material is applied
                    //
                    this.InternalSetShape(shapeReference, new ElementId(material.Id), oldShape.Item2.syncId);
                    this.InternalSetName(shapeReference, shapeName, material, category);
                    return;
                }
            }

            //Phase 2- There was no existing shape, create one
            TransactionManager.Instance.EnsureInTransaction(Document);

            Autodesk.Revit.DB.DirectShape ds;

            //generate the geometry correctly depending on the type of geo
            var tessellatedShape = GenerateTessellatedGeo(shapeReference, new ElementId(material.Id));

            //actually construct the directshape revit element
            ds = NewDirectShape(tessellatedShape,
                                Document, new ElementId(category.Id),
                                DirectShape.DYNAMO_DIRECTSHAPE_APP_GUID.ToString(), shapeName);

            InternalSetDirectShape(ds);
            InternalSetName(shapeReference, shapeName, material, category);
            //generate a new syncId for trace
            var traceData = new DirectShapeState(this, Guid.NewGuid().ToString(), new ElementId(material.Id));

            //add the elementID:tracedata to the tags dictionary on the real protogeometry input
            shapeReference.Tags.AddTag(this.InternalElementId.ToString(), traceData);
            TransactionManager.Instance.TransactionTaskDone();

            ElementBinder.SetRawDataForTrace(traceData);
        }
예제 #3
0
        /// <summary>
        /// Set the SpatialFieldManager and PrimitiveId in Thread Local Storage
        /// </summary>
        /// <param name="manager"></param>
        /// <param name="primitiveId"></param>
        protected void SetElementAndPrimitiveIdForTrace(SpatialFieldManager manager, int primitiveId)
        {
            if (manager == null)
            {
                throw new Exception();
            }

            SpmPrimitiveIdPair idPair = new SpmPrimitiveIdPair();

            idPair.SpatialFieldManagerID = manager.Id.IntegerValue;
            idPair.PrimitiveID           = primitiveId;
            ElementBinder.SetRawDataForTrace(idPair);
        }
예제 #4
0
        /// <summary>
        /// Handling exceptions when calling the initializing function
        /// </summary>
        /// <param name="init"></param>
        protected void SafeInit(Action init)
        {
            TransactionManager.Instance.EnsureInTransaction(DocumentManager.Instance.CurrentDBDocument);

            var elementManager = ElementIDLifecycleManager <int> .GetInstance();

            var element = ElementBinder.GetElementFromTrace <Autodesk.Revit.DB.Element>(Document);
            int count   = 0;
            int id      = 0;

            if (null != element)
            {
                id    = element.Id.IntegerValue;
                count = elementManager.GetRegisteredCount(id);
            }
            try
            {
                init();
            }
            catch (Exception e)
            {
                //If the element is newly created and bound but the creation is aborted because
                //of an exception, it need to be unregistered.
                if (element == null && InternalElementId != null)
                {
                    elementManager.UnRegisterAssociation(Id, this);
                    internalId = null;
                    throw e;
                }
                else if (element != null)
                {
                    //If the internal element has already been bound, and if the registered count has increased,
                    //it need to be unregistered.
                    if (elementManager.GetRegisteredCount(id) == count + 1)
                    {
                        elementManager.UnRegisterAssociation(Id, this);
                        internalId = null;
                    }

                    //It means that the updating operation failed, an attemption of making a new element is made.
                    ElementBinder.SetRawDataForTrace(null);
                    SafeInit(init);
                }
                else
                {
                    throw e;
                }
            }
        }
        /// <summary>
        /// Set the SpatialFieldManager and PrimitiveId in Thread Local Storage
        /// </summary>
        /// <param name="manager"></param>
        /// <param name="keyValues"></param>
        protected void SetElementAndRefPrimitiveIdsForTrace(SpatialFieldManager manager, Dictionary <Reference, int> keyValues)
        {
            if (manager == null)
            {
                throw new Exception();
            }

            var idPair = new SpmRefPrimitiveIdListPair
            {
                SpatialFieldManagerID = manager.Id.IntegerValue,
                RefIdPairs            = keyValues
            };

            ElementBinder.SetRawDataForTrace(idPair);
        }
예제 #6
0
        /// <summary>
        /// Set the SpatialFieldManager and PrimitiveId in Thread Local Storage
        /// </summary>
        /// <param name="manager"></param>
        /// <param name="primitiveIds"></param>
        protected void SetElementAndPrimitiveIdsForTrace(SpatialFieldManager manager, List <int> primitiveIds)
        {
            if (manager == null)
            {
                throw new Exception();
            }

            var idPair = new SpmPrimitiveIdPair
            {
                SpatialFieldManagerID = manager.Id.IntegerValue,
                PrimitiveIds          = primitiveIds
            };

            ElementBinder.SetRawDataForTrace(idPair);
        }
예제 #7
0
        public void RawTraceInteractionTest()
        {
            var elementId = new SerializableId
            {
                IntID    = 42,
                StringID = "{BE507CAC-7F23-43D6-A2B4-13F6AF09046F}"
            };

            //Raw write
            ElementBinder.SetRawDataForTrace(elementId);
            elementId = null;

            //Readback
            elementId = (SerializableId)ElementBinder.GetRawDataFromTrace();
            Assert.IsTrue(elementId.IntID == 42);
            Assert.IsTrue(elementId.StringID == "{BE507CAC-7F23-43D6-A2B4-13F6AF09046F}");
        }
예제 #8
0
        /// <summary>
        /// Sets the internalDirectShape's shape to point to some geometry,
        /// this method also generates tessellated geometry from the protogeometry object
        /// and sets the material of the generated Revit faces
        /// </summary>
        private void InternalSetShape(DesignScriptEntity shapeReference, ElementId materialId, string currentSyncId)
        {
            //if the elementID for the current directShape revitElement exists on the input Geometry AND
            //the value stored at that key is equal to the materialId we're trying to set AND
            //the previousState's syncId (in the tags dictionary) equals the current syncId (from trace)
            //then we do not need to regenerate

            //first lookup the state on the input geometry
            var previousState = shapeReference.Tags.LookupTag(this.InternalElementId.ToString()) as DirectShapeState;

            //then compare values
            if (previousState != null && previousState.materialId == materialId.IntegerValue && previousState.syncId == currentSyncId)
            {
                return;
            }

            TransactionManager.Instance.EnsureInTransaction(Document);

            var tessellatedShape = GenerateTessellatedGeo(shapeReference, materialId);

            this.InternalDirectShape.SetShape(tessellatedShape);

            //update the value in trace, since we had to modify the geometry we need a new syncId
            var updatedTraceData = new DirectShapeState(this, Guid.NewGuid().ToString(), materialId);

            ElementBinder.SetRawDataForTrace(updatedTraceData);
            //place new values in the tags dict
            if (shapeReference.Tags.LookupTag(this.InternalElementId.ToString()) == null)
            {
                shapeReference.Tags.AddTag(this.InternalElementId.ToString(), updatedTraceData);
            }
            else
            {
                var storedState = shapeReference.Tags.LookupTag(this.InternalElementId.ToString()) as DirectShapeState;
                storedState.syncId     = updatedTraceData.syncId;
                storedState.materialId = updatedTraceData.materialId;
                storedState.IntID      = updatedTraceData.IntID;
                storedState.StringID   = updatedTraceData.StringID;
            }

            TransactionManager.Instance.TransactionTaskDone();
        }
예제 #9
0
        public void RawTraceInteractionTestWithMultipleIDs()
        {
            var elementIDs = new MultipleSerializableId
            {
                IntIDs    = { 42, 20 },
                StringIDs = { "{BE507CAC-7F23-43D6-A2B4-13F6AF09046F}", "{A79294BF-6D27-4B86-BEE9-D6921C11D495}" }
            };

            //Raw write
            ElementBinder.SetRawDataForTrace(elementIDs);
            elementIDs = null;

            //Readback
            var readback = (MultipleSerializableId)ElementBinder.GetRawDataFromTrace();

            //Verify that the data is correct
            Assert.IsTrue(readback.IntIDs.Count == 2);
            Assert.IsTrue(readback.IntIDs[0] == 42);
            Assert.IsTrue(readback.IntIDs[1] == 20);
            Assert.IsTrue(readback.StringIDs.Count == 2);
            Assert.IsTrue(readback.StringIDs[0].Equals("{BE507CAC-7F23-43D6-A2B4-13F6AF09046F}"));
            Assert.IsTrue(readback.StringIDs[1].Equals("{A79294BF-6D27-4B86-BEE9-D6921C11D495}"));
        }
예제 #10
0
        /// <summary>
        /// Initialize a Level element
        /// </summary>
        /// <param name="elevation"></param>
        /// <param name="name"></param>
        private void InitLevel(double elevation, string name)
        {
            //Phase 1 - Check to see if the object exists and should be rebound
            var oldEle = ElementBinder.GetElementAndTraceData <Autodesk.Revit.DB.Level, LevelTraceData>(Document);

            //There was an element, bind & mutate
            if (oldEle != null)
            {
                InternalSetLevel(oldEle.Item1);
                InternalSetElevation(elevation);
                InternalSetName(oldEle.Item2.InputName, name);
                return;
            }

            //There was no element, create a new one
            TransactionManager.Instance.EnsureInTransaction(Document);

            Autodesk.Revit.DB.Level level;

            if (Document.IsFamilyDocument)
            {
                level = Autodesk.Revit.DB.Level.Create(Document, elevation);
            }
            else
            {
                level = Autodesk.Revit.DB.Level.Create(Document, elevation);
            }

            InternalSetLevel(level);
            InternalSetName(string.Empty, name);
            var traceData = new LevelTraceData(this, name);

            TransactionManager.Instance.TransactionTaskDone();

            ElementBinder.SetRawDataForTrace(traceData);
        }
예제 #11
0
        public void TwoInstancesOfSerializableIdAreEqual()
        {
            var elementID = new SerializableId
            {
                IntID    = 42,
                StringID = "{BE507CAC-7F23-43D6-A2B4-13F6AF09046F}"
            };

            var elementID2 = new SerializableId
            {
                IntID    = 42,
                StringID = "{BE507CAC-7F23-43D6-A2B4-13F6AF09046F}"
            };

            //Raw write
            ElementBinder.SetRawDataForTrace(elementID);
            elementID = null;

            //Readback
            var readback = (SerializableId)ElementBinder.GetRawDataFromTrace();

            //verify that the id extracted from trace is equal to the new instance
            Assert.IsTrue(readback.Equals(elementID2));
        }
예제 #12
0
        public void TwoInstancesOfMultSerializableIdAreEqual()
        {
            var elementIDs = new MultipleSerializableId
            {
                IntIDs    = { 42, 20 },
                StringIDs = { "{BE507CAC-7F23-43D6-A2B4-13F6AF09046F}", "{A79294BF-6D27-4B86-BEE9-D6921C11D495}" }
            };

            var elementIDs2 = new MultipleSerializableId
            {
                IntIDs    = { 42, 20 },
                StringIDs = { "{BE507CAC-7F23-43D6-A2B4-13F6AF09046F}", "{A79294BF-6D27-4B86-BEE9-D6921C11D495}" }
            };

            //Raw write
            ElementBinder.SetRawDataForTrace(elementIDs);
            elementIDs = null;

            //Readback
            var readback = (MultipleSerializableId)ElementBinder.GetRawDataFromTrace();

            //verify that the id extracted from trace is equal to the new instance
            Assert.IsTrue(readback.Equals(elementIDs2));
        }