Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Mirrors
SuperElastix
Commits
0e23bb37
Commit
0e23bb37
authored
Jan 31, 2017
by
Floris Berendsen
Browse files
ENH: WIP: Compose Blueprints SuperElastix/SuperElastix#28
parent
9e413ef7
Changes
5
Hide whitespace changes
Inline
Side-by-side
Modules/Core/Blueprints/include/selxBlueprint.h
View file @
0e23bb37
...
...
@@ -60,6 +60,9 @@ public:
bool
ConnectionExists
(
ComponentNameType
upstream
,
ComponentNameType
downstream
)
const
;
// "functional" composition of blueprints is done by adding settings of other to this blueprint. Redefining/overwriting properties is not allowed and returns false.
bool
ComposeWith
(
std
::
unique_ptr
<
Blueprint
>
const
&
other
);
// Returns a vector of the Component names at the incoming direction
ComponentNamesType
GetInputNames
(
const
ComponentNameType
name
)
const
;
...
...
Modules/Core/Blueprints/src/selxBlueprint.cxx
View file @
0e23bb37
...
...
@@ -102,6 +102,14 @@ Blueprint
}
bool
Blueprint
::
ComposeWith
(
std
::
unique_ptr
<
Blueprint
>
const
&
other
)
{
return
this
->
m_Pimple
->
ComposeWith
(
other
);
}
Blueprint
::
ComponentNamesType
Blueprint
::
GetOutputNames
(
const
ComponentNameType
name
)
const
...
...
Modules/Core/Blueprints/src/selxBlueprintImpl.cxx
View file @
0e23bb37
...
...
@@ -93,7 +93,16 @@ inline edge_label_writer< ParameterMapType >
return
edge_label_writer
<
ParameterMapType
>
(
p
);
}
//Used in CloneGraph
struct
Blueprint
::
BlueprintImpl
::
vertex_copier
{
ComponentPropertyType
&
from
;
ComponentPropertyType
&
to
;
void
operator
()(
Blueprint
::
BlueprintImpl
::
GraphType
::
vertex_descriptor
input
,
Blueprint
::
BlueprintImpl
::
GraphType
::
vertex_descriptor
output
)
const
{
//TODO !
//to[output] = { from[input]};
}
};
bool
Blueprint
::
BlueprintImpl
::
SetComponent
(
ComponentNameType
name
,
ParameterMapType
parameterMap
)
...
...
@@ -219,6 +228,82 @@ Blueprint::BlueprintImpl
return
boost
::
edge_by_label
(
upstream
,
downstream
,
this
->
m_Graph
).
second
;
}
Blueprint
::
BlueprintImpl
::
GraphType
Blueprint
::
BlueprintImpl
::
CloneGraph
(
void
)
const
{
GraphType
clone
;
// TODO!
// boost::copy_graph(this->m_Graph, clone, boost::vertex_copy(vertex_copier()));
return
clone
;
}
bool
Blueprint
::
BlueprintImpl
::
ComposeWith
(
std
::
unique_ptr
<
Blueprint
>
const
&
other
)
{
// Make a backup of the current blueprint status in case composition fails
GraphType
graph_backup
=
this
->
CloneGraph
();
for
(
auto
const
&
componentName
:
other
->
GetComponentNames
())
{
// Does other blueprint use component with a name that already exists?
if
(
this
->
ComponentExists
(
componentName
))
{
// Component exists, check if properties can be merged
auto
ownProperties
=
this
->
GetComponent
(
componentName
);
auto
othersProperties
=
other
->
GetComponent
(
componentName
);
for
(
auto
const
&
othersEntry
:
othersProperties
)
{
// Does other use a property key that already exists in this component?
if
(
ownProperties
.
count
(
othersEntry
.
first
))
{
auto
&&
ownValues
=
ownProperties
[
othersEntry
.
first
];
auto
&&
otherValues
=
othersEntry
.
second
;
// Are the property values equal?
if
(
ownValues
.
size
()
!=
otherValues
.
size
())
{
// No, based on the number of values we see that it is different. Blueprints cannot be Composed
this
->
m_Graph
=
graph_backup
;
return
false
;
}
else
{
ParameterValueType
::
const_iterator
ownValue
;
ParameterValueType
::
const_iterator
otherValue
;
for
(
ownValue
=
ownValues
.
begin
(),
otherValue
=
otherValues
.
begin
();
ownValue
!=
ownValues
.
end
();
++
ownValue
,
++
otherValue
)
{
if
(
*
otherValue
!=
*
ownValue
)
{
// No, at least one value is different. Blueprints cannot be Composed
this
->
m_Graph
=
graph_backup
;
return
false
;
}
}
}
}
else
{
// Property key doesn't exist yet, add entry to this component
auto
ownProperties
=
this
->
GetComponent
(
componentName
);
ownProperties
[
othersEntry
.
first
]
=
othersEntry
.
second
;
this
->
SetComponent
(
componentName
,
ownProperties
);
}
}
}
else
{
// Create Component copying properties of other
this
->
SetComponent
(
componentName
,
other
->
GetComponent
(
componentName
));
}
}
return
true
;
}
Blueprint
::
ComponentNamesType
Blueprint
::
BlueprintImpl
...
...
Modules/Core/Blueprints/src/selxBlueprintImpl.h
View file @
0e23bb37
...
...
@@ -25,6 +25,8 @@
#include
"boost/graph/directed_graph.hpp"
#include
"boost/graph/labeled_graph.hpp"
#include
"boost/graph/copy.hpp"
// for ComposeWith
#include
"selxBlueprint.h"
namespace
selx
{
...
...
@@ -46,6 +48,8 @@ struct Blueprint::BlueprintImpl {
ParameterMapType
parameterMap
;
};
struct
vertex_copier
;
typedef
boost
::
labeled_graph
<
boost
::
adjacency_list
<
boost
::
vecS
,
...
...
@@ -89,6 +93,8 @@ struct Blueprint::BlueprintImpl {
bool
ConnectionExists
(
ComponentNameType
upstream
,
ComponentNameType
downstream
)
const
;
bool
ComposeWith
(
std
::
unique_ptr
<
Blueprint
>
const
&
other
);
// Returns a vector of the Component names at the incoming direction
ComponentNamesType
GetInputNames
(
const
ComponentNameType
name
)
const
;
...
...
@@ -99,6 +105,8 @@ struct Blueprint::BlueprintImpl {
ConnectionIndexType
GetConnectionIndex
(
ComponentNameType
upsteam
,
ComponentNameType
downstream
)
const
;
GraphType
CloneGraph
(
void
)
const
;
GraphType
m_Graph
;
};
...
...
Modules/Core/Blueprints/test/selxBlueprintTest.cxx
View file @
0e23bb37
...
...
@@ -105,6 +105,51 @@ TEST_F( BlueprintTest, SetGetDeleteConnection )
}
TEST_F
(
BlueprintTest
,
Compose
)
{
std
::
unique_ptr
<
Blueprint
>
baseBlueprint
;
EXPECT_NO_THROW
(
baseBlueprint
=
std
::
unique_ptr
<
Blueprint
>
(
new
Blueprint
()));
baseBlueprint
->
SetComponent
(
"Component0"
,
{
{
"OperationType"
,
{
"Transform"
}
}
});
baseBlueprint
->
SetComponent
(
"Component1"
,
{
{
"OperationType"
,
{
"Source"
}
},
{
"Dimensionality"
,
{
"3"
}
}
});
// compose-in a new 3rd component Component2
std
::
unique_ptr
<
Blueprint
>
nonConflictingBlueprint0
;
EXPECT_NO_THROW
(
nonConflictingBlueprint0
=
std
::
unique_ptr
<
Blueprint
>
(
new
Blueprint
()));
nonConflictingBlueprint0
->
SetComponent
(
"Component2"
,
{
{
"OperationType"
,
{
"Sink"
}
}
});
EXPECT_TRUE
(
baseBlueprint
->
ComposeWith
(
nonConflictingBlueprint0
));
// compose-in additional properties of Component0 and Component1
std
::
unique_ptr
<
Blueprint
>
nonConflictingBlueprint1
;
EXPECT_NO_THROW
(
nonConflictingBlueprint1
=
std
::
unique_ptr
<
Blueprint
>
(
new
Blueprint
()));
nonConflictingBlueprint1
->
SetComponent
(
"Component0"
,
{
{
"TranformationGroup"
,
{
"Diffeomorphic"
}
},
{
"PixelType"
,
{
"float"
}
}
});
nonConflictingBlueprint1
->
SetComponent
(
"Component1"
,
{
{
"NameOfClass"
,
{
"ImageSourceClass"
}
}
});
EXPECT_TRUE
(
baseBlueprint
->
ComposeWith
(
nonConflictingBlueprint1
)
);
// compose-in existing component with existing property key, but equal property value(s). Nothing happens actually (i.e. idempotency)
std
::
unique_ptr
<
Blueprint
>
nonConflictingBlueprint2
;
EXPECT_NO_THROW
(
nonConflictingBlueprint2
=
std
::
unique_ptr
<
Blueprint
>
(
new
Blueprint
()));
nonConflictingBlueprint2
->
SetComponent
(
"Component0"
,
{
{
"PixelType"
,
{
"float"
}
}
});
EXPECT_TRUE
(
baseBlueprint
->
ComposeWith
(
nonConflictingBlueprint2
));
// trying to overwrite properties fails
std
::
unique_ptr
<
Blueprint
>
conflictingBlueprint0
;
EXPECT_NO_THROW
(
conflictingBlueprint0
=
std
::
unique_ptr
<
Blueprint
>
(
new
Blueprint
()));
conflictingBlueprint0
->
SetComponent
(
"Component1"
,
{
{
"Dimensionality"
,
{
"2"
}
},
{
"PixelType"
,
{
"float"
}
}
});
EXPECT_FALSE
(
baseBlueprint
->
ComposeWith
(
conflictingBlueprint0
));
}
//TEST_F( BlueprintTest, WriteBlueprint )
//{
// std::unique_ptr< Blueprint > blueprint;
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment