From 15ff322ec1074c5ad3c46d8b3955b6592b67fa60 Mon Sep 17 00:00:00 2001 From: Richard Christie Date: Fri, 13 Sep 2024 10:07:19 +1200 Subject: [PATCH] Simplify major/minor count calculations --- .../meshtypes/meshtype_3d_tubenetwork1.py | 20 ++++--- .../meshtypes/meshtype_3d_wholebody2.py | 54 +++++++++---------- src/scaffoldmaker/utils/tubenetworkmesh.py | 19 ++----- tests/test_wholebody2.py | 4 +- 4 files changed, 38 insertions(+), 59 deletions(-) diff --git a/src/scaffoldmaker/meshtypes/meshtype_3d_tubenetwork1.py b/src/scaffoldmaker/meshtypes/meshtype_3d_tubenetwork1.py index 8f720a3a..63d519e5 100644 --- a/src/scaffoldmaker/meshtypes/meshtype_3d_tubenetwork1.py +++ b/src/scaffoldmaker/meshtypes/meshtype_3d_tubenetwork1.py @@ -4,8 +4,7 @@ from scaffoldmaker.meshtypes.meshtype_1d_network_layout1 import MeshType_1d_network_layout1 from scaffoldmaker.meshtypes.scaffold_base import Scaffold_base from scaffoldmaker.scaffoldpackage import ScaffoldPackage -from scaffoldmaker.utils.tubenetworkmesh import ( - calculateElementsCountAcrossMinor, TubeNetworkMeshBuilder, TubeNetworkMeshGenerateData) +from scaffoldmaker.utils.tubenetworkmesh import TubeNetworkMeshBuilder, TubeNetworkMeshGenerateData class MeshType_3d_tubenetwork1(Scaffold_base): @@ -202,20 +201,19 @@ def generateBaseMesh(cls, region, options): networkMesh = networkLayout.getConstructionObject() defaultAroundCount = options["Number of elements around"] - elementsCountTransition = options["Number of elements across core transition"] + coreTransitionCount = options["Number of elements across core transition"] defaultCoreBoxMinorCount = options["Number of elements across core box minor"] - defaultElementsCountAcrossMajor = calculateElementsCountAcrossMinor( - defaultAroundCount, elementsCountTransition, defaultCoreBoxMinorCount + 2 * elementsCountTransition) + # implementation currently uses major count including transition + defaultCoreMajorCount = defaultAroundCount // 2 - defaultCoreBoxMinorCount + 2 * coreTransitionCount annotationAroundCounts = options["Annotation numbers of elements around"] annotationCoreBoxMinorCounts = options["Annotation numbers of elements across core box minor"] - annotationElementsCountsAcrossMajor = [] + annotationCoreMajorCounts = [] for i in range(len(annotationCoreBoxMinorCounts)): aroundCount = annotationAroundCounts[i] if annotationAroundCounts[i] \ else defaultAroundCount coreBoxMinorCount = annotationCoreBoxMinorCounts[i] if annotationCoreBoxMinorCounts[i] \ else defaultCoreBoxMinorCount - annotationElementsCountsAcrossMajor.append(calculateElementsCountAcrossMinor( - aroundCount, elementsCountTransition, coreBoxMinorCount + 2 * elementsCountTransition)) + annotationCoreMajorCounts.append(aroundCount // 2 - coreBoxMinorCount + 2 * coreTransitionCount) tubeNetworkMeshBuilder = TubeNetworkMeshBuilder( networkMesh, @@ -224,9 +222,9 @@ def generateBaseMesh(cls, region, options): elementsCountThroughWall=options["Number of elements through shell"], layoutAnnotationGroups=layoutAnnotationGroups, annotationElementsCountsAround=annotationAroundCounts, - defaultElementsCountAcrossMajor=defaultElementsCountAcrossMajor, - elementsCountTransition=elementsCountTransition, - annotationElementsCountsAcrossMajor=annotationElementsCountsAcrossMajor, + defaultElementsCountAcrossMajor=defaultCoreMajorCount, + elementsCountTransition=coreTransitionCount, + annotationElementsCountsAcrossMajor=annotationCoreMajorCounts, isCore=options["Core"]) tubeNetworkMeshBuilder.build() diff --git a/src/scaffoldmaker/meshtypes/meshtype_3d_wholebody2.py b/src/scaffoldmaker/meshtypes/meshtype_3d_wholebody2.py index 47bac8a9..1e165d44 100644 --- a/src/scaffoldmaker/meshtypes/meshtype_3d_wholebody2.py +++ b/src/scaffoldmaker/meshtypes/meshtype_3d_wholebody2.py @@ -9,8 +9,7 @@ from scaffoldmaker.annotation.annotationgroup import AnnotationGroup, findOrCreateAnnotationGroupForTerm, \ getAnnotationGroupForTerm from scaffoldmaker.annotation.body_terms import get_body_term -from scaffoldmaker.utils.tubenetworkmesh import ( - calculateElementsCountAcrossMinor, TubeNetworkMeshBuilder, TubeNetworkMeshGenerateData) +from scaffoldmaker.utils.tubenetworkmesh import TubeNetworkMeshBuilder, TubeNetworkMeshGenerateData from scaffoldmaker.utils.zinc_utils import exnode_string_from_nodeset_field_parameters from cmlibs.zinc.node import Node @@ -199,7 +198,7 @@ def getDefaultNetworkLayoutScaffoldPackage(cls, parameterSetName): class MeshType_3d_wholebody2(Scaffold_base): """ - Generates a 3-D hermite bifurcating tube network, with linear basis through wall. + Generates a 3-D hermite bifurcating tube network with core representing the human body. """ @classmethod @@ -226,7 +225,7 @@ def getDefaultOptions(cls, parameterSetName="Default"): "Number of elements around torso": 12, "Number of elements around arm": 8, "Number of elements around leg": 8, - "Number of elements through wall": 1, + "Number of elements through shell": 1, "Target element density along longest segment": 5.0, "Show trim surfaces": False, "Use Core": True, @@ -246,7 +245,7 @@ def getDefaultOptions(cls, parameterSetName="Default"): options["Number of elements around torso"] = 24 options["Number of elements around arm"] = 12 options["Number of elements around leg"] = 16 - options["Number of elements through wall"] = 2 + options["Number of elements through shell"] = 1 options["Target element density along longest segment"] = 10.0 options["Number of elements across core box minor"] = 4 @@ -260,7 +259,7 @@ def getOrderedOptionNames(cls): "Number of elements around torso", "Number of elements around arm", "Number of elements around leg", - "Number of elements through wall", + "Number of elements through shell", "Target element density along longest segment", "Show trim surfaces", "Use Core", @@ -318,8 +317,8 @@ def checkOptions(cls, options): if (minElementsCountAround is None) or (options[key] < minElementsCountAround): minElementsCountAround = options[key] - if options["Number of elements through wall"] < 0: - options["Number of elements through wall"] = 1 + if options["Number of elements through shell"] < 0: + options["Number of elements through shell"] = 1 if options["Target element density along longest segment"] < 1.0: options["Target element density along longest segment"] = 1.0 @@ -327,11 +326,7 @@ def checkOptions(cls, options): if options["Number of elements across core transition"] < 1: options["Number of elements across core transition"] = 1 - elementsCountCoreTransition = options['Number of elements across core transition'] - maxElementsCountCoreBoxMinor = calculateElementsCountAcrossMinor( - minElementsCountAround, elementsCountCoreTransition, 2 + 2 * elementsCountCoreTransition) \ - - 2 * elementsCountCoreTransition - + maxElementsCountCoreBoxMinor = minElementsCountAround // 2 - 2 for key in [ "Number of elements across core box minor" ]: @@ -362,21 +357,20 @@ def generateBaseMesh(cls, region, options): layoutAnnotationGroups = networkLayout.getAnnotationGroups() networkMesh = networkLayout.getConstructionObject() - elementsCountCoreBoxMinor = options["Number of elements across core box minor"] - elementsCountCoreTransition = options['Number of elements across core transition'] - elementsCountCoreMinor = elementsCountCoreBoxMinor + 2 * elementsCountCoreTransition - annotationElementsCountsAround = [] - annotationElementsCountsAcross = [] + coreBoxMinorCount = options["Number of elements across core box minor"] + coreTransitionCount = options['Number of elements across core transition'] + annotationAroundCounts = [] + # implementation currently uses major count including transition + annotationCoreMajorCounts = [] for layoutAnnotationGroup in layoutAnnotationGroups: - elementsCountAround = 0 - elementsCountCoreMajor = 0 + aroundCount = 0 + coreMajorCount = 0 name = layoutAnnotationGroup.getName() if name in ["head", "torso", "arm", "leg"]: - elementsCountAround = options["Number of elements around " + name] - elementsCountCoreMajor = calculateElementsCountAcrossMinor( - elementsCountAround, elementsCountCoreTransition, elementsCountCoreMinor) - annotationElementsCountsAround.append(elementsCountAround) - annotationElementsCountsAcross.append(elementsCountCoreMajor) + aroundCount = options["Number of elements around " + name] + coreMajorCount = aroundCount // 2 - coreBoxMinorCount + 2 * coreTransitionCount + annotationAroundCounts.append(aroundCount) + annotationCoreMajorCounts.append(coreMajorCount) isCore = options["Use Core"] @@ -384,12 +378,12 @@ def generateBaseMesh(cls, region, options): networkMesh, targetElementDensityAlongLongestSegment=options["Target element density along longest segment"], defaultElementsCountAround=options["Number of elements around head"], - elementsCountThroughWall=options["Number of elements through wall"], + elementsCountThroughWall=options["Number of elements through shell"], layoutAnnotationGroups=layoutAnnotationGroups, - annotationElementsCountsAround=annotationElementsCountsAround, - defaultElementsCountAcrossMajor=annotationElementsCountsAcross[-1], - elementsCountTransition=elementsCountCoreTransition, - annotationElementsCountsAcrossMajor=annotationElementsCountsAcross, + annotationElementsCountsAround=annotationAroundCounts, + defaultElementsCountAcrossMajor=annotationCoreMajorCounts[-1], + elementsCountTransition=coreTransitionCount, + annotationElementsCountsAcrossMajor=annotationCoreMajorCounts, isCore=isCore) tubeNetworkMeshBuilder.build() diff --git a/src/scaffoldmaker/utils/tubenetworkmesh.py b/src/scaffoldmaker/utils/tubenetworkmesh.py index 8775ac31..c32dd862 100644 --- a/src/scaffoldmaker/utils/tubenetworkmesh.py +++ b/src/scaffoldmaker/utils/tubenetworkmesh.py @@ -193,9 +193,9 @@ def __init__(self, networkSegment, pathParametersList, elementsCountAround, elem super(TubeNetworkMeshSegment, self).__init__(networkSegment, pathParametersList) self._isCore = isCore self._elementsCountAround = elementsCountAround - self._elementsCountAcrossMajor = elementsCountAcrossMajor - self._elementsCountAcrossMinor = calculateElementsCountAcrossMinor( - elementsCountAround, elementsCountTransition, elementsCountAcrossMajor) + self._elementsCountAcrossMajor = elementsCountAcrossMajor # includes 2 * elementsCountTransition + self._elementsCountAcrossMinor = \ + self._elementsCountAround // 2 - elementsCountAcrossMajor + 4 * elementsCountTransition self._elementsCountTransition = elementsCountTransition # if self._isCore and self._elementsCountTransition > 1: @@ -2882,16 +2882,3 @@ def resampleTubeCoordinates(rawTubeCoordinates, fixedElementsCountAlong=None, sd1[p] = smoothCubicHermiteDerivativesLoop(sx[p], td1, fixAllDirections=True) return sx, sd1, sd2, sd12 - - -def calculateElementsCountAcrossMinor(elementsCountAround, elementsCountTransition, elementsCountAcrossMajor): - """ - Calculate number of elements across minor axis of shield mesh based on number around, number of radial - transition elements, and number of elements across major. - Assumes these can work together. - :param elementsCountAround: Number of elements around the circumference. - :param elementsCountTransition: Number of transition layers between the core box and the outside. - :param elementsCountAcrossMajor: Number of elements across the major axis. - :return: Number of elements across the minor axis. - """ - return elementsCountAround // 2 + 4 * elementsCountTransition - elementsCountAcrossMajor diff --git a/tests/test_wholebody2.py b/tests/test_wholebody2.py index c4aad8c1..c7610463 100644 --- a/tests/test_wholebody2.py +++ b/tests/test_wholebody2.py @@ -32,7 +32,7 @@ def test_wholebody2_core(self): self.assertEqual(12, options["Number of elements around torso"]) self.assertEqual(8, options["Number of elements around arm"]) self.assertEqual(8, options["Number of elements around leg"]) - self.assertEqual(1, options["Number of elements through wall"]) + self.assertEqual(1, options["Number of elements through shell"]) self.assertEqual(5.0, options["Target element density along longest segment"]) self.assertEqual(False, options["Show trim surfaces"]) self.assertEqual(True, options["Use Core"]) @@ -121,7 +121,7 @@ def test_wholebody2_tube(self): self.assertEqual(12, options["Number of elements around torso"]) self.assertEqual(8, options["Number of elements around arm"]) self.assertEqual(8, options["Number of elements around leg"]) - self.assertEqual(1, options["Number of elements through wall"]) + self.assertEqual(1, options["Number of elements through shell"]) self.assertEqual(5.0, options["Target element density along longest segment"]) self.assertEqual(False, options["Show trim surfaces"]) self.assertEqual(True, options["Use Core"])