Skip to content

Commit 23d0179

Browse files
authored
Adsk Contrib - Merge configs feature (#2179)
* Config merge rewrite, part 1 Signed-off-by: Doug Walker <[email protected]> (cherry picked from commit 08a3adf) Signed-off-by: Doug Walker <[email protected]> * Add API for config and colorspace merge Signed-off-by: Doug Walker <[email protected]> (cherry picked from commit fadef86) Signed-off-by: Doug Walker <[email protected]> * Prototype of merge avoid duplicates feature Signed-off-by: Doug Walker <[email protected]> (cherry picked from commit 008ad27) Signed-off-by: Doug Walker <[email protected]> * Unit test fix Signed-off-by: Doug Walker <[email protected]> (cherry picked from commit cbc0f0e) Signed-off-by: Doug Walker <[email protected]> * Improve duplicates detection Signed-off-by: Doug Walker <[email protected]> (cherry picked from commit 9871ef4) Signed-off-by: Doug Walker <[email protected]> * Fix unit test Signed-off-by: Doug Walker <[email protected]> (cherry picked from commit 914b2f0) Signed-off-by: Doug Walker <[email protected]> * Various merge fixes Signed-off-by: Doug Walker <[email protected]> (cherry picked from commit f60e990) Signed-off-by: Doug Walker <[email protected]> * Add more tests and clean-up Signed-off-by: Doug Walker <[email protected]> * Improve comments Signed-off-by: Doug Walker <[email protected]> * Remove CreateFromFile support Signed-off-by: Doug Walker <[email protected]> * Add Python binding Signed-off-by: Doug Walker <[email protected]> * Improve view transform comparison Signed-off-by: Doug Walker <[email protected]> * Address Remi's comments Signed-off-by: Doug Walker <[email protected]> * Fix build breaks Signed-off-by: Doug Walker <[email protected]> --------- Signed-off-by: Doug Walker <[email protected]>
1 parent 9ebb770 commit 23d0179

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+16082
-11
lines changed

include/OpenColorIO/OpenColorAppHelpers.h

Lines changed: 352 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,358 @@ class OCIOEXPORT MixingColorSpaceManager
533533

534534
extern OCIOEXPORT std::ostream & operator<<(std::ostream &, const MixingColorSpaceManager &);
535535

536+
/**
537+
* The ConfigMergingParameters class holds the options that control how a merge is done.
538+
*
539+
* In terms of OCIOM file, it represent one of the merges in an OCIOM file.
540+
*
541+
*/
542+
class OCIOEXPORT ConfigMergingParameters
543+
{
544+
public:
545+
546+
enum MergeStrategies
547+
{
548+
/// Combine elements of the base and input configs, with the input taking priority.
549+
STRATEGY_PREFER_INPUT = 0,
550+
/// Combine elements of the base and input configs, with the base taking priority.
551+
STRATEGY_PREFER_BASE,
552+
/// Use only the input elements for that section of the config.
553+
STRATEGY_INPUT_ONLY,
554+
/// Use only the base elements for that section of the config.
555+
STRATEGY_BASE_ONLY,
556+
/// The elements in the input config are removed from the base config. (If the names
557+
/// match, the item is removed, even if the content is not identical.)
558+
STRATEGY_REMOVE,
559+
/// Strategy has not been set yet.
560+
STRATEGY_UNSPECIFIED
561+
};
562+
563+
static ConfigMergingParametersRcPtr Create();
564+
565+
ConfigMergingParametersRcPtr createEditableCopy() const;
566+
567+
/// Set the file name of the base config. This is used along with the search path of
568+
/// the ConfigMerger object.
569+
void setBaseConfigName(const char * baseConfig);
570+
const char * getBaseConfigName() const;
571+
572+
/// Set the file name of the input config. This is used along with the search path of
573+
/// the ConfigMerger object.
574+
void setInputConfigName(const char * inputConfig);
575+
const char * getInputConfigName() const;
576+
577+
/// Set a name to use for this merger. This may be used as the input or base config name
578+
/// in subsequent mergers.
579+
void setOutputName(const char * outputName);
580+
const char * getOutputName() const;
581+
582+
// Options
583+
584+
/// Set the default strategy. This will be used if the strategy for a given config section
585+
/// is not set, and will be used for basic attributes such as the config description.
586+
/// Default = STRATEGY_PREFER_INPUT.
587+
void setDefaultStrategy(const ConfigMergingParameters::MergeStrategies strategy);
588+
ConfigMergingParameters::MergeStrategies getDefaultStrategy() const;
589+
590+
/// Set a prefix to add to the family of input config items. (It must use '/' as the
591+
/// separator and will be replaced by the actual family separator of the config.)
592+
void setInputFamilyPrefix(const char * prefix);
593+
const char * getInputFamilyPrefix() const;
594+
595+
/// Set a prefix to add to the family of base config items. (It must use '/' as the
596+
/// separator and will be replaced by the actual family separator of the config.)
597+
void setBaseFamilyPrefix(const char * prefix);
598+
const char * getBaseFamilyPrefix() const;
599+
600+
/// If true, items from the input config will be higher in the file than those of the
601+
/// base config. Default = true.
602+
void setInputFirst(bool enabled);
603+
bool isInputFirst() const;
604+
605+
/// If true, throw an exception rather than log a warning when a conflict is detected.
606+
/// Default = false.
607+
void setErrorOnConflict(bool enabled);
608+
bool isErrorOnConflict() const;
609+
610+
/// If true, a color space from the input config is compared against those of the base
611+
/// config. If it is mathematically equivalent, it is not added. Instead, its name and
612+
/// aliases are added to the original color space. Default = true.
613+
void setAvoidDuplicates(bool enabled);
614+
bool isAvoidDuplicates() const;
615+
616+
/// If true, the reference spaces of the base and input config are compared and color
617+
/// spaces from the input config will be adjusted to use the reference space of the base.
618+
/// If the interchange roles are not set, heuristics will be used to try and determine
619+
/// the reference space. Default = true.
620+
void setAdjustInputReferenceSpace(bool enabled);
621+
bool isAdjustInputReferenceSpace() const;
622+
623+
// Overrides
624+
625+
/// Override the name of the merged config.
626+
void setName(const char * mergedConfigName);
627+
const char * getName() const;
628+
629+
/// Override the description of the merged config.
630+
void setDescription(const char * mergedConfigDesc);
631+
const char * getDescription() const;
632+
633+
/// Override a context variable in the merged config.
634+
void addEnvironmentVar(const char * name, const char * defaultValue);
635+
/// Get the number of context variable overrides.
636+
int getNumEnvironmentVars() const;
637+
const char * getEnvironmentVar(int index) const;
638+
const char * getEnvironmentVarValue(int index) const;
639+
640+
/// Override the search_path of the merged config.
641+
void setSearchPath(const char * path);
642+
void addSearchPath(const char * path);
643+
const char * getSearchPath() const;
644+
645+
/// Override the active_displays of the merged config.
646+
void setActiveDisplays(const char * displays);
647+
const char * getActiveDisplays() const;
648+
649+
/// Override the active_views of the merged config.
650+
void setActiveViews(const char * views);
651+
const char * getActiveViews() const;
652+
653+
/// Override the inactive_colorspaces of the merged config.
654+
void setInactiveColorSpaces(const char * colorspaces);
655+
const char * getInactiveColorSpaces() const;
656+
657+
// Config section strategies
658+
659+
/// Set the merge strategy for the roles section.
660+
void setRoles(MergeStrategies strategy);
661+
MergeStrategies getRoles() const;
662+
663+
/// Set the merge strategy for the file_rules section.
664+
void setFileRules(MergeStrategies strategy);
665+
MergeStrategies getFileRules() const;
666+
667+
/// Set the merge strategy for the displays/views section.
668+
/// This includes shared_views, displays, viewing_rules,
669+
/// virtual_display, active_display, and active_views.
670+
void setDisplayViews(MergeStrategies strategy);
671+
MergeStrategies getDisplayViews() const;
672+
673+
/// Set the merge strategy for the view_transforms section.
674+
/// This includes the view_transforms and default_view_transform.
675+
void setViewTransforms(MergeStrategies strategy);
676+
MergeStrategies getViewTransforms() const;
677+
678+
/// Set the merge strategy for the looks section.
679+
void setLooks(MergeStrategies strategy);
680+
MergeStrategies getLooks() const;
681+
682+
/// Set the merge strategy for the color spaces section.
683+
/// This includes colorspaces, display_colorspaces, environment, search_path,
684+
/// family_separator, and inactive_colorspaces.
685+
void setColorspaces(MergeStrategies strategy);
686+
MergeStrategies getColorspaces() const;
687+
688+
/// Set the merge strategy for the named_transforms section.
689+
void setNamedTransforms(MergeStrategies strategy);
690+
MergeStrategies getNamedTransforms() const;
691+
692+
ConfigMergingParameters(const ConfigMergingParameters &) = delete;
693+
ConfigMergingParameters& operator= (const ConfigMergingParameters &) = delete;
694+
695+
/// Do not use (needed only for pybind11).
696+
~ConfigMergingParameters();
697+
698+
private:
699+
ConfigMergingParameters();
700+
701+
static void deleter(ConfigMergingParameters * c);
702+
703+
class Impl;
704+
Impl * m_impl;
705+
Impl * getImpl() { return m_impl; }
706+
const Impl * getImpl() const { return m_impl; }
707+
};
708+
709+
extern OCIOEXPORT std::ostream & operator<<(std::ostream &, const ConfigMergingParameters &);
710+
711+
/**
712+
* The ConfigMerger class is the controller for the merging process.
713+
*
714+
* It may be read from or serialized to an OCIOM file.
715+
*
716+
* It is controlling the search_path to find the base and input config, and the merge parameters.
717+
*
718+
* It contains an instance of ConfigMergingParameters for each merge present under the "merge"
719+
* section.
720+
*
721+
* For example, consider the following OCIOM file contents:
722+
*
723+
* ociom_version: 1.0
724+
* search_path:
725+
* - /usr/local/configs
726+
* - .
727+
* merge:
728+
* Merge_ADD_THIS:
729+
* [...]
730+
* Merge_ADD_THAT:
731+
* [...]
732+
*
733+
* For this OCIOM, there would be two instances of ConfigMergingParameters.
734+
* One for the merge with output name "Merge_ADD_THIS" and one for "Merge_ADD_THAT".
735+
*
736+
* Where the [...] sections have the following structure:
737+
*
738+
* Merge_ADD_THIS:
739+
* base: base.ocio
740+
* input: input.ocio
741+
* options:
742+
* input_family_prefix: ""
743+
* base_family_prefix: ""
744+
* input_first: true
745+
* error_on_conflict: false
746+
* default_strategy: PreferInput
747+
* avoid_duplicates: true
748+
* adjust_input_reference_space: true
749+
* overrides:
750+
* name: ""
751+
* description: ""
752+
* search_path: ""
753+
* environment: {}
754+
* active_displays: []
755+
* active_views: []
756+
* inactive_colorspaces: []
757+
* params:
758+
* roles:
759+
* strategy: PreferBase
760+
* file_rules:
761+
* strategy: PreferInput
762+
* display-views:
763+
* strategy: InputOnly
764+
* view_transforms:
765+
* strategy: InputOnly
766+
* looks:
767+
* strategy: BaseOnly
768+
* colorspaces:
769+
* strategy: PreferInput
770+
* named_transform:
771+
* strategy: Remove
772+
*
773+
* The indentation is significant and must be as shown. Default items may be omitted.
774+
*
775+
*/
776+
class OCIOEXPORT ConfigMerger
777+
{
778+
public:
779+
static ConfigMergerRcPtr Create();
780+
781+
// Create by parsing an OCIOM file.
782+
static ConstConfigMergerRcPtr CreateFromFile(const char * filepath);
783+
784+
ConfigMergerRcPtr createEditableCopy() const;
785+
786+
/// These search paths are used to locate the input and base config.
787+
/// Set the entire search path. The ':' character is used to separate paths.
788+
void setSearchPath(const char * path);
789+
/// Add a single path to the search paths.
790+
void addSearchPath(const char * path);
791+
/// Get the number of search paths.
792+
int getNumSearchPaths() const;
793+
const char * getSearchPath(int index) const;
794+
795+
/**
796+
* \brief Set the home directory used to resolve relative search paths.
797+
*
798+
* The working directory defaults to the location of the OCIOM file. It is used to convert
799+
* any relative paths to absolute. If no search paths have been set, the working directory
800+
* will be used as the fallback search path.
801+
*/
802+
void setWorkingDir(const char * dirname);
803+
const char * getWorkingDir() const;
804+
805+
/// Get the parameters for one of the merges. Returns null if index is out of range.
806+
ConfigMergingParametersRcPtr getParams(int index) const;
807+
int getNumConfigMergingParameters() const;
808+
void addParams(ConfigMergingParametersRcPtr params);
809+
810+
/**
811+
* \brief Execute the merge(s) based on the merger object.
812+
*
813+
* Execute the merge(s) based on the merger object that was previously populated by using
814+
* ConfigMerger::CreateFromFile or created from scratch by using ConfigMerger::Create() and
815+
* programmatically configuring it.
816+
*
817+
* \return a merger object (call getMergedConfig to obtain the result)
818+
*/
819+
ConstConfigMergerRcPtr mergeConfigs() const;
820+
821+
/// Get the final merged config.
822+
ConstConfigRcPtr getMergedConfig() const;
823+
/// Get one of the merged configs (if there are a series of merges). Returns null
824+
/// if index is out of range.
825+
ConstConfigRcPtr getMergedConfig(int index) const;
826+
int getNumMergedConfigs() const;
827+
828+
/// Serialize to the OCIOM file format.
829+
void serialize(std::ostream& os) const;
830+
831+
/// Set the version of the OCIOM file format.
832+
void setVersion(unsigned int major, unsigned int minor);
833+
unsigned int getMajorVersion() const;
834+
unsigned int getMinorVersion() const;
835+
836+
ConfigMerger(const ConfigMerger &) = delete;
837+
ConfigMerger & operator=(const ConfigMerger &) = delete;
838+
839+
/// Do not use (needed only for pybind11).
840+
~ConfigMerger();
841+
842+
private:
843+
ConfigMerger();
844+
845+
static void deleter(ConfigMerger * c);
846+
847+
class Impl;
848+
Impl * m_impl;
849+
Impl * getImpl() { return m_impl; }
850+
const Impl * getImpl() const { return m_impl; }
851+
};
852+
853+
extern OCIOEXPORT std::ostream & operator<<(std::ostream &, const ConfigMerger &);
854+
855+
namespace ConfigMergingHelpers
856+
{
857+
858+
/**
859+
* \brief Merge the input into the base config, using the supplied merge parameters.
860+
*
861+
* \param params ConfigMergingParameters controlling the merger.
862+
* \param params The base config.
863+
* \param params The input config to merge.
864+
* \return The merged config object.
865+
*/
866+
extern OCIOEXPORT ConfigRcPtr MergeConfigs(const ConfigMergingParametersRcPtr & params,
867+
const ConstConfigRcPtr & baseConfig,
868+
const ConstConfigRcPtr & inputConfig);
869+
870+
/**
871+
* \brief Merge a single color space into the base config, using the supplied merge parameters.
872+
*
873+
* Note that the AdjustInputReferenceSpace merge parameter will be ignored and set to false.
874+
* To use automatic reference space conversion, add the color space to an input config that
875+
* has the necessary interchange role set.
876+
*
877+
* \param params ConfigMergingParameters controlling the merger.
878+
* \param params The base config.
879+
* \param params The input color space to merge.
880+
* \return The merged config object.
881+
*/
882+
extern OCIOEXPORT ConfigRcPtr MergeColorSpace(const ConfigMergingParametersRcPtr & params,
883+
const ConstConfigRcPtr & baseConfig,
884+
const ConstColorSpaceRcPtr & colorspace);
885+
886+
} // ConfigMergingHelpers
887+
536888
} // namespace OCIO_NAMESPACE
537889

538890
#endif // INCLUDED_OCIO_OPENCOLORAPPHELPERS_H

include/OpenColorIO/OpenColorIO.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1326,6 +1326,11 @@ class OCIOEXPORT Config
13261326
*/
13271327
void addNamedTransform(const ConstNamedTransformRcPtr & namedTransform);
13281328

1329+
/**
1330+
* \brief Remove a named transform. (Does nothing if name is not found.)
1331+
*/
1332+
void removeNamedTransform(const char * name);
1333+
13291334
/// Clear all named transforms.
13301335
void clearNamedTransforms();
13311336

@@ -1737,7 +1742,7 @@ class OCIOEXPORT FileRules
17371742
/// Does include default rule. Result will be at least 1.
17381743
size_t getNumEntries() const noexcept;
17391744

1740-
/// Get the index from the rule name.
1745+
/// Get the index from the rule name. Throws if the rule is not found.
17411746
size_t getIndexForRule(const char * ruleName) const;
17421747

17431748
/// Get name of the rule.

include/OpenColorIO/OpenColorTypes.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,13 @@ class LegacyViewingPipeline;
266266
typedef OCIO_SHARED_PTR<LegacyViewingPipeline> LegacyViewingPipelineRcPtr;
267267
typedef OCIO_SHARED_PTR<const LegacyViewingPipeline> ConstLegacyViewingPipelineRcPtr;
268268

269+
class ConfigMergingParameters;
270+
typedef OCIO_SHARED_PTR<ConfigMergingParameters> ConfigMergingParametersRcPtr;
271+
typedef OCIO_SHARED_PTR<const ConfigMergingParameters> ConstConfigMergingParametersRcPtr;
272+
273+
class ConfigMerger;
274+
typedef OCIO_SHARED_PTR<ConfigMerger> ConfigMergerRcPtr;
275+
typedef OCIO_SHARED_PTR<const ConfigMerger> ConstConfigMergerRcPtr;
269276

270277
template <class T, class U>
271278
inline OCIO_SHARED_PTR<T> DynamicPtrCast(OCIO_SHARED_PTR<U> const & ptr)

0 commit comments

Comments
 (0)