예제 #1
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);
        }
예제 #2
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();
        }