The DgnPlatform copying framework defines an algorithm to produce a valid copy of an element. More...
Classes | |
struct | ElementCopyContext |
Use the ElementCopyContext class to copy elements. More... | |
struct | ElementCopyContext::IEventHandler |
Element copy event handler. More... | |
Enumerations | |
enum | CopyContextLevelOption { ByUserPreference = 0, CopyIfNotFound = 1, CopyIfDifferent = 2, CopyAlways = 3, AlreadyRemapped = 4, CopyByNumber = 5 } |
How to handle levels when copying an element between files. More... | |
enum | SharedCellNameConflicts { Undefined = -1, None = 0, HasDefId = 1, All = 2 } |
Functions | |
virtual void | OnElementCopied (EditElementHandleR eh, ElementCopyContext &, bool isPre)=0 |
virtual void | OnLevelCloned (ULong destLevelId, ULong sourceLevelId, bool uniqueName, ElementCopyContext &cc)=0 |
virtual void | OnProcessDatabaseLinkages (EditElementHandleR eh, ElementCopyContext &) |
Intialization | |
~ElementCopyContext () | |
ElementCopyContext (ElementCopyContext const &) | |
ElementCopyContext & | operator= (ElementCopyContext const &) |
ElementCopyContext (DgnModelRefP dest) | |
Intialize an ElementCopyContext. More... | |
Copying an element | |
StatusInt | DoCopy (EditElementHandleR eh) |
Turn the specified element into a copy of the original. More... | |
Source and destination models | |
void | SetDestinationModelRef (DgnModelRefP) |
Identify the model that is the destination of the copy. More... | |
DgnModelP | GetDestinationModel () |
Query the model that is the destination of the copy. More... | |
DgnModelRefP | GetDestinationModelRef () |
Query the model that is the destination of the copy. More... | |
void | SetSourceModelRef (DgnModelRefP) |
Identify the model that is the source of the copy. More... | |
DgnModelRefP | GetSourceModelRef (ElementHandleCP el=0) |
Query the model or reference attachment that is the source of the copy. More... | |
DgnModelP | GetSourceCache (ElementHandleCP el=0) |
Query the model that is the source of the copy. More... | |
bool | IsCopyFromReference () |
Query if the source model is a reference attachment of the destination model. (Returns false if the destination model is itself a reference attachment to some other model.) More... | |
bool | IsSameCache (ElementHandleCP eh=0) |
Query if the copy starts and ends in the same model (possibly going through a reference transform). More... | |
bool | IsSameFile (ElementHandleCP eh=0) |
Query if the copy starts and ends in the same file (possibly different models). More... | |
void | GetModels (DgnModelRefP *srcModelRefP, DgnModelRefP *destModelP, bool *sameCacheP, bool *sameFileP, ElementHandleCP elemHandle=0) |
Query source and destination models. More... | |
void | SetModelFromElmdscr (bool useElmdscr) |
Set the copy context so that the model ref from the element descriptor is used as the source model ref for the copy, unless it is NULL in which case the source model ref is used. More... | |
bool | GetModelFromElmdscr () const |
IEventHandler - Reacting to DoCopy | |
static void | AddHandler (IEventHandler &handler) |
Register a handler to react when DoCopy is called. More... | |
static void | DropHandler (IEventHandler &handler) |
Un-register a handler. More... | |
Copy options | |
void | SetWriteElements (bool writeAllElements) |
Set the copy context value that determines whether the element descriptor being copied will get written to the destination model ref. More... | |
bool | GetWriteElements () const |
Get the current value of the write elements option. More... | |
void | SetMatchDimToDestination (bool changeDimension) |
Setting this option to false in the copy context will cause the element descriptor passed in not to take on the dimensionality (2D/3D) of the destination model ref. More... | |
bool | GetMatchDimToDestination () const |
Get the current value of the match element dimension to destination model option. More... | |
void | SetScaleReferenceDimensions (bool) |
Set to control how the value of a dimension in a reference is scaled when copied to the destination model. More... | |
bool | GetScaleReferenceDimensions () const |
Get the current value of the scale reference dimensions option. More... | |
void | SetTransformToDestination (bool transformToDestination) |
Defines whether copied elements should be scaled to match the units in the destination model. More... | |
bool | GetTransformToDestination () const |
Get the current value of transform to destination option. More... | |
void | SetAssignNewGGs (bool assignNewGGs) |
Defines whether copied elements should maintain their current graphic group or should be assigned to a new group. More... | |
bool | GetAssignNewGGs () const |
Get the current value of the assign new graphic group option. More... | |
void | SetAssignNewNodes (bool assignNewNodes) |
Defines whether copied elements should maintain their current text node numbers or should be assigned a new number. More... | |
bool | GetAssignNewNodes () const |
Get the current value of the assign new text node number option. More... | |
void | SetViewport (ViewportP vp) |
Sets the view that will be used to flatten the elements if the source model is 3D and the destination model is 2D. More... | |
ViewportP | GetViewport () const |
Get the current viewport used for a flatten direction when copying from a 3d source model to a 2d destination model. More... | |
void | SetLevelHandling (CopyContextLevelOption levelOption) |
Determine the way in which levels are brought from the source model ref to the destination model ref. More... | |
void | SetKeepRefColorIndexOnCopy (bool) |
Set to control how 0-255 color indices are remapped. Set to true to preserve color index instead of searching for a matching RGB. More... | |
bool | GetKeepRefColorIndexOnCopy () |
Get the current value of the reference color index remap option. More... | |
void | SetSharedCellNameConflicts (SharedCellNameConflicts) |
Specify what to do when a name conflict is encountered when deep-copying a shared cell definition. More... | |
SharedCellNameConflicts | GetSharedCellNameConflicts () const |
Get the current value of the option that controls how shared cell name conflicts are resolved. More... | |
void | SetDontPlaceTagsInGG (bool) |
Set the option to control whether tag elements in a graphic group are copied to a new graphic group. More... | |
bool | GetDontPlaceTagsInGG () const |
Get the current value of the option for tags and graphic groups. More... | |
void | SetDisableAnnotationScaling (bool b) |
Direct that annotation scale should not be transformed during the copy. More... | |
bool | GetDisableAnnotationScaling () const |
Get current value of annotation scaling option. More... | |
The DgnPlatform copying framework defines an algorithm to produce a valid copy of an element.
The copying framework is implemented by the ElementCopyContext class, with help from DependencyManager, Bentley::DgnPlatform::ElementHandler, and Bentley::DgnPlatform::XAttributeHandler.
Copying an element is not usually as simple as duplicating its data. Copying must adjust:
Most adjustments can be done in several ways. The copying framework algorithm includes the options and strategies that can be applied when making necessary adjustments.
The copying framework delegates the work of making adjustments to element and XAttribute handlers, as described in detail below.
The ElementCopyContext helper object holds remapping data that is used by the copying algorithm and by handlers. This remapping data can be applied to and shared by multiple elements for efficiency and to support dependency remapping.
The ElementCopyContext object can also hold custom data during a copy operation that can be accessed by handler methods across multiple elements. See ElementCopyContext::AddCustomData.
The ElementCopyContext::DoCopy method transforms the element that you pass to it from an element in the source model to an element in the destination model. That is, DoCopy modifies the element that you pass in. DoCopy optionally writes the transformed element to the destination model (this is the default). See ElementCopyContext::SetWriteElements.
See ElementCopying Code Samples for examples.
The copying framework may transform the units, dimensionality, and possibly the geometry of an element when copying between models. Other types of transformations may also be necessary. ElementCopyContext cooperates with element handlers to do these transformations. ElementCopyContext first calls:
ElementCopyContext then calls the following handler methods as necessary, depending on the source and destination models:
Also, when copying an element between two files, ElementCopyContext ensures that all supporting data, including color tables, levels and styles, are present in the destination model, in order to create a copy that is equivalent to the source.
In some cases, ElementCopyContext must copy the supporting data from the source file to the destination file. In other cases, it may find that the necessary data is already present in the destination file. Styles and levels are resolved by name, so if a style with the same name exists in both the source and destination models, the element will be remapped to the style in the destination. For reasons of efficiency, you should use the same ElementCopyContext object when copying multiple elements.
ElementCopyContext modifies the transformed element to reference supporting data in the destination file.
Note: In order to ensure that all changes including copied levels and styles are written to the destination file, the ElementCopyContext object must be destroyed or you must call SetDestinationModelRef(NULL) on the ElementCopyContext object before you call ProcessChanges on the destination file.
Even when copying elements within a single model, you should use ElementCopyContext because it maintains dependencies between elements. ElementCopyContext collaborates with DependencyManagerLinkage and IXAttributePointerContainerHandler to allow handlers to remap their dependency pointers. A handler's Handler::PreprocessCopy method can also get involved in remapping dependency pointers.
If an element has XAttributes that point to other elements, it is the job of the handler of the element or of the XAttributes to control how copy affects those pointers. Some common patterns are:
The DgnPlatform element copying framework offers mechanisms to help handlers implement these patterns.
-# The application creates an ElementCopyContext object, specifies the destination model, and sets copying options. -# The application calls ElementCopyContext::DoCopy (dependent), which calls: -# ElementCopyContext::IEventHandler::OnElementCopied with true -# \ref XAttributeCopyingAlgorithm -# Handler::PreprocessCopy -# Note: The element handler can modify or discard XAttributes at this time -# \ref DependencyPointerPreProcessing -# Handler::ConvertTo2d or Handler::ConvertTo3d, if necessary -# Handler::ChangeUnits, if necessary -# Handler::ApplyTransform, if necessary -# ITxn::AddElement (optional) -# ElementCopyContext::IEventHandler::OnElementCopied with false -# The application calls ElementCopyContext::DoCopy on other elements -# The application calls DependencyManger::ProcessAffected, which calls -# \ref DependencyPointerRemapping
ElementCopyContext::DoCopy does the following:
-# For each XAttribute on dependent -# Schedules a copy of the original XAttribute on dependent [\ref Note5] -# Calls XAttributeHandler::PreprocessCopy [\ref Note5] -# handler can make deep copies of its root elements, if desired, by calling ElementCopyContext::DeepCopyRoot. [\ref Note1] -# or, handler can implement singleton semantics, if desired. [\ref Note2] -# handler should then call PersistentElementPath::PreprocessCopy, which does this: [\ref Note3] -# If requested, attempts to deep-copy the root: -# If root has already been copied, then points to the copy. -# Otherwise, copies the root by calling ElementCopyContext::DeepCopyRoot and points to the copy. -# Otherwise, replaces the PersistentElementPath data with a remap key which identifies the original root element. -# This root will be remapped by DependencyManger::ProcessAffected in the last step below.
Dependending on the copy options of the dependency pointer and on the type of the root, ElementCopyContext will either deep-copy a root element or set up for remapping.
If the strategy calls for deep-copying, ElementCopyContext will call Handler::OnPreProcessDeepCopy to allow the handler to decide how to handle the deep-copy. As outlined above, a handler might want to deep-copy the root, maintain a singleton reference, drop the reference, or opt for remapping.
If the strategy does not call for deep-copying or if the handler's OnPreProcessDeepCopy opts for remapping, then ElementCopyContext will set up the remapping process. Dependency pointer remapping is a three-part process.
ElementCopyContext conducts the first phase of dependency pointer copying by replacing each dependency pointer stored in a DependencyLinkage or an XAttribute with a 64 bit key that identifies the modelRef and elementRef of the target (root) element. This key identifies an entry in the element copying remap table. ElementCopyContext does this by:
DependencyManager::ProcessAffected conducts the final phase of dependency pointer copying by replacing the remap keys stored in DependencyLinkages and XAttributes with element identifiers to link copied dependent elements with original or copied root elements. DependencyManager::ProcessAffected does this by:
Whenever remapping fails, ProcessAffected calls Handler::_OnPostprocessCopyRemapRestore on the affected dependent element. This method allows the handler of the dependent element to repair the dependency pointer, e.g., turn a far reference into a near reference.
1. Decide if you want a deep copy or not. If so, call ElementCopyContext::DeepCopyRoot on the root. This sets up a remap table entry for it.
2. Maintaining a singleton is a special case of making a deep copy. Rather than always deep-copying the root, you search for it in the destination model (by some means known to your handler) and only deep-copy it if not found.
3. The PersistentElementPath::CopyOption argument controls how PersistentElementPath::PreprocessCopy handles pointers.
If you made a deep copy of the root or if the root is a singleton, call PersistentElementPath::PreprocessCopy and pass COPYCONTEXT_DeepCopyRootsAlways. That tells PreprocessCopy to point to the copy immediately. If you did not make a deep copy and want to preserve the original reference or if you want to leave the copying up to the caller, then call PreprocessCopy with COPYOPTION_RemapRootsWithinSelection. That tells PreprocessCopy to store a remap key, to be resolved later by PreprocessCopyRemapIds.
4. If your XAttribute handler's PreprocessCopyRemapIds method returns non-zero, then your XAttribute will be removed from the host element. The handler might do this if it detects a broken link. Or, the handler might do this in order to implement the policy of always dropping a pointer when the dependent is copied.
5. If the caller schedules an XAttribute on the element descriptor before calling ElementCopyContext::DoCopy, then ElementCopyContext::DoCopy will not try to schedule another copy of that XAttribute and will not call its PreprocessCopy method.
|
strong |
How to handle levels when copying an element between files.
|
strong |
|
static |
Register a handler to react when DoCopy is called.
[in] | handler | the handler to register. This function calls AddRef on handler. |
StatusInt DoCopy | ( | EditElementHandleR | eh | ) |
Turn the specified element into a copy of the original.
Units and ids are remapped from the source to the destination model.
eh | The element that is to be transformed. |
|
static |
Un-register a handler.
[in] | handler | the handler to un-register. This function calls Release on handler. |
ElementCopyContext | ( | ElementCopyContext const & | ) |
|
explicit |
Intialize an ElementCopyContext.
dest | The destination model |
true
); true
); true
); true
); true
); false
. bool GetAssignNewGGs | ( | ) | const |
Get the current value of the assign new graphic group option.
bool GetAssignNewNodes | ( | ) | const |
Get the current value of the assign new text node number option.
DgnModelP GetDestinationModel | ( | ) |
Query the model that is the destination of the copy.
DgnModelRefP GetDestinationModelRef | ( | ) |
Query the model that is the destination of the copy.
bool GetDisableAnnotationScaling | ( | ) | const |
Get current value of annotation scaling option.
bool GetDontPlaceTagsInGG | ( | ) | const |
Get the current value of the option for tags and graphic groups.
bool GetKeepRefColorIndexOnCopy | ( | ) |
Get the current value of the reference color index remap option.
bool GetMatchDimToDestination | ( | ) | const |
Get the current value of the match element dimension to destination model option.
bool GetModelFromElmdscr | ( | ) | const |
void GetModels | ( | DgnModelRefP * | srcModelRefP, |
DgnModelRefP * | destModelP, | ||
bool * | sameCacheP, | ||
bool * | sameFileP, | ||
ElementHandleCP | elemHandle = 0 |
||
) |
Query source and destination models.
srcModelRefP | [optional] source model or reference attachment |
destModelP | [optional] destination model or reference attachment. |
sameCacheP | [optional] are source and destination the same cache? (Possibly involving a reference transform) |
sameFileP | [optional] are source and destination models in the same file? |
elemHandle | [optional] If not NULL, get source model from this element, if ElementCopyContext has none or if CLONE_OPTIONS_ModelFromElmdscr was specified |
bool GetScaleReferenceDimensions | ( | ) | const |
Get the current value of the scale reference dimensions option.
SharedCellNameConflicts GetSharedCellNameConflicts | ( | ) | const |
Get the current value of the option that controls how shared cell name conflicts are resolved.
DgnModelP GetSourceCache | ( | ElementHandleCP | el = 0 | ) |
Query the model that is the source of the copy.
DgnModelRefP GetSourceModelRef | ( | ElementHandleCP | el = 0 | ) |
Query the model or reference attachment that is the source of the copy.
bool GetTransformToDestination | ( | ) | const |
Get the current value of transform to destination option.
ViewportP GetViewport | ( | ) | const |
Get the current viewport used for a flatten direction when copying from a 3d source model to a 2d destination model.
bool GetWriteElements | ( | ) | const |
Get the current value of the write elements option.
bool IsCopyFromReference | ( | ) |
Query if the source model is a reference attachment of the destination model. (Returns false
if the destination model is itself a reference attachment to some other model.)
bool IsSameCache | ( | ElementHandleCP | eh = 0 | ) |
Query if the copy starts and ends in the same model (possibly going through a reference transform).
bool IsSameFile | ( | ElementHandleCP | eh = 0 | ) |
Query if the copy starts and ends in the same file (possibly different models).
|
pure virtual |
|
pure virtual |
|
virtual |
ElementCopyContext& operator= | ( | ElementCopyContext const & | ) |
void SetAssignNewGGs | ( | bool | assignNewGGs | ) |
Defines whether copied elements should maintain their current graphic group or should be assigned to a new group.
Note that all elements with the same graphic group number will be remapped to the same new number as long as the same context is used.
true
in the constructor. assignNewGGs | defines whether to assign new graphic groups or maintain the current values. |
void SetAssignNewNodes | ( | bool | assignNewNodes | ) |
Defines whether copied elements should maintain their current text node numbers or should be assigned a new number.
true
in the constructor. assignNewNodes | defines whether to assign new text node numbers or maintain the current values. |
void SetDestinationModelRef | ( | DgnModelRefP | ) |
Identify the model that is the destination of the copy.
void SetDisableAnnotationScaling | ( | bool | b | ) |
Direct that annotation scale should not be transformed during the copy.
void SetDontPlaceTagsInGG | ( | bool | ) |
Set the option to control whether tag elements in a graphic group are copied to a new graphic group.
void SetKeepRefColorIndexOnCopy | ( | bool | ) |
Set to control how 0-255 color indices are remapped. Set to true to preserve color index instead of searching for a matching RGB.
void SetLevelHandling | ( | CopyContextLevelOption | levelOption | ) |
Determine the way in which levels are brought from the source model ref to the destination model ref.
CopyContextLevelOption::CopyIfNotFound
in the constructor. levelOption | determines how the levels are handled during a copy. See CopyContextLevelOption. |
void SetMatchDimToDestination | ( | bool | changeDimension | ) |
Setting this option to false
in the copy context will cause the element descriptor passed in not to take on the dimensionality (2D/3D) of the destination model ref.
The value will always be treated as true
if the elements are being written to the file (see SetWriteElements).
true
in the constructor. changeDimension | true to allow elements to be converted to the same dimensionality as the destination model ref; false to keep the elements as they are. |
void SetModelFromElmdscr | ( | bool | useElmdscr | ) |
Set the copy context so that the model ref from the element descriptor is used as the source model ref for the copy, unless it is NULL in which case the source model ref is used.
The primary reason to use this option is for cells that may be from multiple model refs.
false
in the constructor. useElmdscr | true to use the model refs on the element descriptors; false to use the source model set for this copy context. |
void SetScaleReferenceDimensions | ( | bool | ) |
Set to control how the value of a dimension in a reference is scaled when copied to the destination model.
void SetSharedCellNameConflicts | ( | SharedCellNameConflicts | ) |
Specify what to do when a name conflict is encountered when deep-copying a shared cell definition.
This defaults to SharedCellNameConflicts::HasDefId.
void SetSourceModelRef | ( | DgnModelRefP | ) |
Identify the model that is the source of the copy.
The source may be a reference attachment.
void SetTransformToDestination | ( | bool | transformToDestination | ) |
Defines whether copied elements should be scaled to match the units in the destination model.
true
. transformToDestination | defines whether to scale the elements by the difference in units between the models. |
void SetViewport | ( | ViewportP | vp | ) |
Sets the view that will be used to flatten the elements if the source model is 3D and the destination model is 2D.
vp | defines the view to use for flattening if necessary. |
void SetWriteElements | ( | bool | writeAllElements | ) |
Set the copy context value that determines whether the element descriptor being copied will get written to the destination model ref.
Regardless of the value passed in, the additional necessary information (styles, levels, etc.) will be copied to the destination model ref.
true
in the constructor. writeAllElements | true to copy all elements to the destination model ref; false to just copy necessary additional elements. |
~ElementCopyContext | ( | ) |