1- from cmlibs .utils .zinc .finiteelement import get_identifiers , evaluate_field_nodeset_range
1+ from cmlibs .utils .zinc .finiteelement import evaluate_field_nodeset_range , get_identifiers , get_maximum_node_identifier
22from cmlibs .zinc .field import Field
33from cmlibs .zinc .result import RESULT_OK
44
@@ -10,11 +10,25 @@ def _find_missing(lst):
1010 for i in range (x + 1 , y ) if y - x > 1 ]
1111
1212
13- def convert_nodes_to_datapoints (target_region , source_region ):
13+ def convert_nodes_to_datapoints (target_region , source_region , source_nodeset_type = Field .DOMAIN_TYPE_NODES ,
14+ destroy_after_conversion = True ):
15+ """
16+ Converts nodes in the source region to datapoints in the target region, renumbering any existing
17+ datapoints in target region to not clash.
18+ When the source nodeset type is Field.DOMAIN_TYPE_DATAPOINTS, then datapoints are transferred from the
19+ source region to the target region.
20+ :param target_region: Zinc Region to read data into. Existing data points are renumbered to avoid nodes.
21+ :param source_region: Zinc Region containing nodes to transfer.
22+ :param source_nodeset_type: Set to Field.DOMAIN_TYPE_DATAPOINTS or Field.DOMAIN_TYPE_NODES to transfer datapoints
23+ or convert nodes. Datapoint transfer should only be to different regions [default: Field.DOMAIN_TYPE_NODES].
24+ :param destroy_after_conversion: Set to True to destroy nodes that have been successfully converted, or False
25+ to leave intact in source region [default: True].
26+ """
1427 source_fieldmodule = source_region .getFieldmodule ()
1528 target_fieldmodule = target_region .getFieldmodule ()
1629 with ChangeManager (source_fieldmodule ), ChangeManager (target_fieldmodule ):
17- nodes = source_fieldmodule .findNodesetByFieldDomainType (Field .DOMAIN_TYPE_NODES )
30+ # Could be nodes or datapoints.
31+ nodes = source_fieldmodule .findNodesetByFieldDomainType (source_nodeset_type )
1832 if nodes .getSize () > 0 :
1933 datapoints = target_fieldmodule .findNodesetByFieldDomainType (Field .DOMAIN_TYPE_DATAPOINTS )
2034 if datapoints .getSize () > 0 :
@@ -44,11 +58,27 @@ def convert_nodes_to_datapoints(target_region, source_region):
4458 datapoint .setIdentifier (new_identifier )
4559
4660 # transfer nodes as datapoints to target_region
47- buffer = write_to_buffer (source_region , resource_domain_type = Field .DOMAIN_TYPE_NODES )
48- buffer = buffer .replace (bytes ("!#nodeset nodes" , "utf-8" ), bytes ("!#nodeset datapoints" , "utf-8" ))
61+ buffer = write_to_buffer (source_region , resource_domain_type = source_nodeset_type )
62+ if source_nodeset_type == Field .DOMAIN_TYPE_NODES :
63+ buffer = buffer .replace (bytes ("!#nodeset nodes" , "utf-8" ), bytes ("!#nodeset datapoints" , "utf-8" ))
4964 result = read_from_buffer (target_region , buffer )
5065 assert result == RESULT_OK , "Failed to load nodes as datapoints"
51- nodes .destroyAllNodes ()
66+ if destroy_after_conversion :
67+ # note this cannot destroy nodes in use by elements
68+ nodes .destroyAllNodes ()
69+
70+
71+ def copy_fitting_data (target_region , source_region ):
72+ """
73+ Copy nodes and data points from source_region to target_region, converting nodes to data points and
74+ offsetting data point identifiers to not clash. All groups and fields in use are transferred.
75+ This is used for setting up fitting problems where data needs to be in datapoints only.
76+ :param target_region: Zinc Region to read nodes/data into.
77+ :param source_region: Zinc Region containing nodes/data to transfer. Unmodified.
78+ """
79+ for domain_type in [Field .DOMAIN_TYPE_DATAPOINTS , Field .DOMAIN_TYPE_NODES ]:
80+ convert_nodes_to_datapoints (target_region , source_region , source_nodeset_type = domain_type ,
81+ destroy_after_conversion = False )
5282
5383
5484def copy_nodeset (region , nodeset ):
0 commit comments