Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wholebody/withlimbs #207

Open
wants to merge 40 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
09258e8
initial code
elias-soltani Oct 29, 2021
7edf4be
initial code
elias-soltani Oct 29, 2021
9cb9a31
half of the right armpit
elias-soltani Nov 4, 2021
1d7dd85
Changing topology
elias-soltani Nov 10, 2021
e1cd011
Minor changes
elias-soltani Nov 14, 2021
13c6d38
Update annotation terms for the stomach
elias-soltani Dec 6, 2021
231b6e9
lower limbs and torso
elias-soltani Dec 13, 2021
f312641
copied to 2nd one
elias-soltani Jan 5, 2022
b055471
Add neck
elias-soltani Jan 14, 2022
5423bc3
Angle
elias-soltani Jan 17, 2022
43dd08e
fix derivatives
elias-soltani Feb 3, 2022
29aa0fc
changed the armpit
elias-soltani Feb 23, 2022
7fa105c
Make half ellipse of the arm flat.
elias-soltani Mar 24, 2022
7800a47
Add range of elements along cylinder parameter. Add arms,neck and head.
elias-soltani Mar 31, 2022
74328fd
modify the meshtype_1d_bifurcationtree1.py to extract the stickman data.
elias-soltani Apr 1, 2022
5f7f91d
Add stickman
elias-soltani Apr 11, 2022
bd91bea
Modify axes and clean the code and make some classes
elias-soltani Apr 21, 2022
d382b7a
Separate arms from upper torso
elias-soltani Apr 21, 2022
2630f1f
Fix nodes derivatives where different mapping is used for adjacent el…
elias-soltani May 1, 2022
95c4f2e
Change middle box and fix derivatives
elias-soltani May 4, 2022
47fb57d
Fix increasing number of elements issue
elias-soltani May 11, 2022
2cb4322
change the order of options
elias-soltani May 11, 2022
bfc2d21
Fix sphere bad element
elias-soltani May 17, 2022
d2a67af
Rename bifurcation to trifurcation
elias-soltani May 17, 2022
84989a9
Remove unused functions
elias-soltani May 17, 2022
175d27c
Bifurcation elements
elias-soltani May 18, 2022
d2fab56
Add the cylinders for the legs
elias-soltani May 20, 2022
766cdb7
Fix the lower limbs elements part1
elias-soltani Jul 26, 2022
aff8711
Fix derivatives for lower limb elementes
elias-soltani Jul 28, 2022
c3c849c
stickman control for legs
elias-soltani Jul 28, 2022
00077a9
Clean up a little bit
elias-soltani Jul 28, 2022
4e6d012
Minor changes
elias-soltani Aug 9, 2022
e0b4853
Minor changes
elias-soltani Aug 9, 2022
d48f1e1
rename filenames
elias-soltani Aug 9, 2022
abeda32
conflicts 1
elias-soltani Sep 4, 2022
ebd7da7
Fix conflicts 1
elias-soltani Sep 6, 2022
313329c
Merge branch 'main' into wholebody/withlimbs
elias-soltani Sep 6, 2022
648ac78
Make the stickman same scale as the body scaffold. Get angles from th…
elias-soltani Sep 8, 2022
225f49a
Add left leg centralpath
elias-soltani Sep 19, 2022
dee8ecc
merge main
elias-soltani Jun 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
219 changes: 219 additions & 0 deletions src/scaffoldmaker/meshtypes/meshtype_1d_stickman1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
"""
Generates a 1-D stickman that is used for body posture.
"""

from __future__ import division

from cmlibs.utils.zinc.field import findOrCreateFieldCoordinates, findOrCreateFieldGroup
from cmlibs.utils.zinc.general import ChangeManager
from cmlibs.zinc.element import Element, Elementbasis
from cmlibs.zinc.field import Field
from cmlibs.zinc.node import Node
from scaffoldmaker.meshtypes.scaffold_base import Scaffold_base
from scaffoldmaker.utils import vector
from scaffoldmaker.utils.interpolation import smoothCubicHermiteCrossDerivativesLine


class MeshType_1d_stickman1(Scaffold_base):
'''
classdocs
'''
@staticmethod
def getName():
return '1D Stickman 1'

@staticmethod
def getDefaultOptions(parameterSetName='Default'):
return {
'Coordinate dimensions': 3,
'Arm length': 1.0,
'Leg length': 1.0,
'Left arm angle': 0.0,
'Left leg angle': 1.2,
'Right arm angle': 0.0,
'Right leg angle': 1.2,
}

@staticmethod
def getOrderedOptionNames():
return [
'Coordinate dimensions',
'Arm length',
'Leg length',
'Left arm angle',
'Left leg angle',
'Right arm angle',
'Right leg angle',
]

@staticmethod
def checkOptions(options):
dependentChanges = False

return dependentChanges

@classmethod
def generateBaseMesh(cls, region, options):
"""
:param region: Zinc region to define model in. Must be empty.
:param options: Dict containing options. See getDefaultOptions().
:return: [] empty list of AnnotationGroup
"""

fieldmodule = region.getFieldmodule()
coordinates = findOrCreateFieldCoordinates(fieldmodule, components_count=3)
cache = fieldmodule.createFieldcache()

arm_length = options['Arm length']
leg_length = options['Leg length']
left_arm_angle = options['Left arm angle']
left_leg_angle = options['Left leg angle']
Right_arm_angle = options['Right arm angle']
Right_leg_angle = options['Right leg angle']

six_stick = True
#################
# Create nodes
#################

nodes = fieldmodule.findNodesetByFieldDomainType(Field.DOMAIN_TYPE_NODES)
nodetemplate = nodes.createNodetemplate()
nodetemplate.defineField(coordinates)
nodetemplate.setValueNumberOfVersions(coordinates, -1, Node.VALUE_LABEL_VALUE, 1)
nodetemplate.setValueNumberOfVersions(coordinates, -1, Node.VALUE_LABEL_D_DS1, 1)

nodeIdentifier = 1
height = arm_length + arm_length + leg_length
longitudinal = [0.0, 0.0, 1.0]
transverse = [1.0, 0.0, 0.0]
sagittal = vector.crossproduct3(longitudinal, transverse)
x_head = vector.scaleVector(longitudinal, height)
x_shoulder = vector.scaleVector(longitudinal, 0.75*height)
x_hip = vector.scaleVector(longitudinal, 0.5*height)
x_centre = vector.scaleVector(vector.addVectors([x_shoulder, x_hip], [1, 1]), 0.5)
x_left_hand = vector.scaleVector(vector.rotateVectorAroundVector(transverse,
sagittal, left_arm_angle), arm_length)
x_left_hand = vector.addVectors([x_shoulder, x_left_hand], [1, 1])
x_right_hand = vector.scaleVector(vector.rotateVectorAroundVector(vector.scaleVector(transverse, -1),
sagittal, -Right_arm_angle), arm_length)
x_right_hand = vector.addVectors([x_shoulder, x_right_hand], [1, 1])
x_left_leg = vector.scaleVector(vector.rotateVectorAroundVector(transverse, sagittal,
left_leg_angle), leg_length)
x_left_leg = vector.addVectors([x_hip, x_left_leg], [1, 1])
x_right_leg = vector.scaleVector(vector.rotateVectorAroundVector(vector.scaleVector(transverse, -1),
sagittal, -Right_leg_angle), leg_length)
x_right_leg = vector.addVectors([x_hip, x_right_leg], [1, 1])
if six_stick:
x_list = [x_head, x_shoulder, x_hip, x_right_hand, x_right_leg, x_left_hand, x_left_leg]
else:
x_list = [[0.0, 0.0, 1.0], [0.0, 0.0, 0.75], [0.0, 0.0, 0.5],
[-0.25, 0.0, 0.81], [-0.25, 0.0, 0.25], [0.25, 0.0, 0.81], [0.25, 0.0, 0.25], [-0.5, 0.0, 0.87] , [-0.5, 0.0, 0.0],
[0.5, 0.0, 0.87], [0.5, 0.0, 0.0]]

x_list = [vector.addVectors([x, x_centre], [1, -1]) for x in x_list]
for x in x_list:
node = nodes.createNode(nodeIdentifier, nodetemplate)
cache.setNode(node)
coordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_VALUE, 1, x)
nodeIdentifier += 1

#################
# Create elements
#################

mesh = fieldmodule.findMeshByDimension(1)
linearLagrangeBasis = fieldmodule.createElementbasis(1, Elementbasis.FUNCTION_TYPE_LINEAR_LAGRANGE)
eft = mesh.createElementfieldtemplate(linearLagrangeBasis)
elementtemplate = mesh.createElementtemplate()
elementtemplate.setElementShapeType(Element.SHAPE_TYPE_LINE)
result = elementtemplate.defineField(coordinates, -1, eft)

elementIdentifier = 1
if six_stick:
lines = [[1, 2], [2, 3],
[2, 4], [3, 5],
[2, 6], [3, 7]]
else:
lines = [[1, 2], [2, 3],
[2, 4], [3, 5], [2, 6], [3, 7],
[4, 8], [5, 9], [6, 10], [7, 11]]
for e in lines:
element = mesh.createElement(elementIdentifier, elementtemplate)
element.setNodesByIdentifier(eft, e)
elementIdentifier += 1

return []


def extractPathParametersFromRegion(region, valueLabels, groupName=None):
'''
Returns parameters of all nodes in region in identifier order.
Assumes nodes in region have field coordinates (1 to 3 components).
:param valueLabels: List of parameters required as list of node value labels. e.g. [Node.VALUE_LABEL_VALUE, Node.VALUE_LABEL_D_DS1].
:param groupName: Optional name of Zinc group to get parameters from.
:return: cx, cd1, cd2, cd12 (all padded with zeroes to 3 components)
'''
fieldmodule = region.getFieldmodule()
coordinates = fieldmodule.findFieldByName('coordinates').castFiniteElement()
componentsCount = coordinates.getNumberOfComponents()
assert componentsCount in [ 1, 2, 3 ], 'extractPathParametersFromRegion. Invalid coordinates number of components'
cache = fieldmodule.createFieldcache()

valueLabelsCount = len(valueLabels)
returnValues = [[] for i in range(valueLabelsCount)]
nodes = fieldmodule.findNodesetByFieldDomainType(Field.DOMAIN_TYPE_NODES)
if groupName:
group = fieldmodule.findFieldByName(groupName).castGroup()
nodeGroup = group.getFieldNodeGroup(nodes)
if nodeGroup.isValid():
nodes = nodeGroup.getNodesetGroup()
else:
print('extractPathParametersFromRegion: missing group "' + groupName + '"')
nodeIter = nodes.createNodeiterator()
node = nodeIter.next()
while node.isValid():
cache.setNode(node)
for i in range(valueLabelsCount):
result, values = coordinates.getNodeParameters(cache, -1, valueLabels[i], 1, componentsCount)
for c in range(componentsCount, 3):
values.append(0.0)
returnValues[i].append(values)
node = nodeIter.next()

return returnValues


def setPathParameters(region, nodeValueLabels, nodeValues, editGroupName=None):
'''
Set node parameters for coordinates field in path from listed values.
:param nodeValueLabels: List of nodeValueLabels to set e.g. [ Node.VALUE_LABEL_VALUE, Node.VALUE_LABEL_D_DS1 ]
:param nodeValues: List of values for each type e.g. [ xlist, d1list ]
:param editGroupName: Optional name of existing or new Zinc group to record modified nodes in.
'''
fieldmodule = region.getFieldmodule()
coordinates = fieldmodule.findFieldByName('coordinates').castFiniteElement()
componentsCount = coordinates.getNumberOfComponents()
# following requires at least one value label and node, assumes consistent values and components counts
nodeValueLabelsCount = len(nodeValueLabels)
nodesCount = len(nodeValues[0])
nodes = fieldmodule.findNodesetByFieldDomainType(Field.DOMAIN_TYPE_NODES)
assert nodesCount == nodes.getSize()
with ChangeManager(fieldmodule):
if editGroupName:
editGroup = findOrCreateFieldGroup(fieldmodule, editGroupName, managed=True)
editNodeGroup = editGroup.getFieldNodeGroup(nodes)
if not editNodeGroup.isValid():
editNodeGroup = editGroup.createFieldNodeGroup(nodes)
editNodesetGroup = editNodeGroup.getNodesetGroup()
cache = fieldmodule.createFieldcache()
nodeIter = nodes.createNodeiterator()
node = nodeIter.next()
n = 0
while node.isValid():
cache.setNode(node)
for v in range(nodeValueLabelsCount):
coordinates.setNodeParameters(cache, -1, nodeValueLabels[v], 1, nodeValues[v][n])
if editGroupName:
editNodesetGroup.addNode(node)
node = nodeIter.next()
n += 1
Loading