<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">try:				import xml.etree.cElementTree as ET
except ImportError:	import xml.etree.ElementTree  as ET
import os


class SimulationPart:
	def __init__(self, name, file, material, Ties, Contact, Other, mesh=None, quad=None):
		self.name = name
		self.file = file
		if file.endswith('.stl'):
			stl = os.path.basename(file)
			cwd = os.getcwd()
			self.med = os.path.join(cwd,'MED',stl.replace('.stl', '.med') )
			print(self.med)
		else:		self.med=file
		self.mat = material
		self.mesh = mesh		# will put mesh data here
		self.quad = quad		# None value is first order, otherwise quadratic order
		self.Ties = Ties		# dictionary of name:multiplier for Ties
		self.Contact = Contact	# dictionary of name:multiplier for Contact by proxmity
		self.Other = Other		# dictionary of other things to do

	def __repr__(self):
		# return "{}, {}\t{}\n\tTies:{}\n\tContact:{}".format(self.name.capitalize(),self.mat,self.file,self.Ties,self.Contact)
		# return "Ties:{}\n\tContact:{}".format(self.Ties,self.Contact)
		if self.mesh:	return "{}, {}	MESHED\n	Ties:{}\n	Contact:{}\n	Other:{}".format(self.name.capitalize(), self.mat, self.Ties.keys(), self.Contact.keys(), self.Other.keys())
		else:			return "{}, {}	{}\n	Ties:{}\n	Contact:{}\n	Other:{}".format(self.name.capitalize(), self.mat, os.path.basename(self.file), self.Ties.keys(), self.Contact.keys(), self.Other.keys())


def ReadConnectivity(filename):
	"""Read Connectivity xml file
		makes dictionaries of type dict[name of part] = partData
		returns meshFiles and meshTieConditions (other types of connections can be easily extend)"""
	tree = ET.ElementTree(file=filename)
	ensemble = tree.getroot()			# ensemble is the xml tree version of assembly
	assembly = {}
	for part in list(ensemble):
		name = part.tag
		file = part.find('file').text
		material = part.find('material').text
		quad = part.find('quad')
		#
		#	maybe I should generalize this away from ties and contact somehow...
		#
		ties={}
		if part.find('Tie'):
			for elem in list(part.find('Tie')):
				elemType = elem.get('type')
				if elemType=='proximity'  or  elemType=='normals' or elemType=='contains' or elemType==None:
					if elemType==None:
						elemType='proximity'	# Set to the established default
					if   elem.get('multiplier'):		mult = float(elem.get('multiplier'))
					elif part.get('multiplier'):		mult = float(part.get('multiplier'))
					elif ensemble.get('multiplier'):	mult = float(ensemble.get('multiplier'))
					else:
						if 'proximity'  == elemType:	mult = 1.0
						elif 'normals'  == elemType:	mult = 0.0
						elif 'contains' == elemType:	mult = 0.0
					if elemType=='contains':		ties[elem.tag] = {elemType:( mult, elem.get('contains') )}
					else:							ties[elem.tag] = {elemType:  mult}
				elif elemType=='local' or elemType=='local_normals' or  elemType=='new':
					if elem.get('threshold'):		ties[elem.tag] = {elemType:  float(elem.get('threshold'))}
					else:							ties[elem.tag] = {elemType:  0.0}
				else:	print('elemType {} not recognized!'.format(elemType))
		contact={}
		if part.find('Contact'):
			for elem in list(part.find('Contact')):
				elemType = elem.get('type')
				if elemType=='proximity'  or  elemType=='normals' or elemType=='contains' or elemType=='local' or elemType=='local_normals':
					if   elem.get('multiplier'):		mult = float(elem.get('multiplier'))
					elif part.get('multiplier'):		mult = float(part.get('multiplier'))
					elif ensemble.get('multiplier'):	mult = float(ensemble.get('multiplier'))
					else:
						if   elemType == 'proximity':	mult = 1.0
						elif elemType == 'normals':		mult = 0.0
						elif elemType == 'contains':	mult = 0.0
					if elemType=='contains':		contact[elem.tag] = {elemType:(mult, elem.get('contains'))}
					else:							contact[elem.tag] = {elemType: mult}
				elif elemType=='local' or elemType=='local_normals' or  elemType=='new':
					if elem.get('threshold'):		ties[elem.tag] = {elemType:  float(elem.get('threshold'))}
					else:							ties[elem.tag] = {elemType:  0.0}
				else:	# elemType == None
					# check if a type was specified as part of a larger group
					if part.find('Contact').get('type'):	elemType = part.find('Contact').get('type')
					elif part.get('contact'):				elemType = part.get('contact')
					elif ensemble.get('contact'):			elemType = ensemble.get('contact')
					else:									elemType =  'all'
					#
					#	repeat the same elemType search from above
					#
					if elemType == 'proximity' or elemType == 'normals' or elemType=='contains':
						if elem.get('multiplier'):				mult = float(elem.get('multiplier'))
						elif part.get('multiplier'):			mult = float(part.get('multiplier'))
						elif ensemble.get('multiplier'):		mult = float(ensemble.get('multiplier'))
						else:
							if   elemType == 'proximity':		mult = 1.0
							elif elemType == 'normals':			mult = 0.0
							elif elemType == 'contains':		mult = 0.0
						if elemType == 'contains':		contact[elem.tag] = {elemType:( mult, elem.get('contains') )}
						else:							contact[elem.tag] = {elemType:  mult}
					else:								contact[elem.tag] = {elemType:None}
		other = {}
		if part.find('Other'):
			for elem in list(part.find('Other')):
				if   elem.tag == 'Vector':		other['Vector'] = tuple(float(i) for i in elem.get('vector').split(','))
				elif elem.tag == 'Remaining':	other['Remaining']=''		# creates a group that is all surfaces not in any other group
		assembly[part.tag] = SimulationPart(name, file, material, ties, contact, other, quad=quad)
		# print assembly[part.tag]
	CheckConnectivity(assembly)
	return assembly

def RemoveDoubleCounting(assembly):
	"""Read and Test Connectivity rely on duplicate data
		i.e. having A&amp;B means having B&amp;A
		but sometimes I only want it once.
		This function eliminates that redundancy.
		returns the reduced connect"""
	print('Removing redundant entries in Contact and Tie conditions')
	for part in assembly.itervalues():
		for contactName in part.Contact:	del assembly[contactName].Contact[part.name]
		for tiedName in part.Ties:			del assembly[tiedName].Ties[part.name]

def CheckConnectivity(assembly):
	"""Verify that connections are listed for both parts
		i.e. if PartA is connected to PartB, PartB will also be connect to PartA"""
	good=True
	for name, part in assembly.items():
		for tiedName in part.Ties:
			if name not in assembly[tiedName].Ties:
				print('\n\nUnrecipricated Behavior!!!',)
				print('{} is Tied to {}'.format(name, tiedName))
				good = False
		for contactName in part.Contact:
			if name not in assembly[contactName].Contact:
				print('\n\nUnrecipricated Behavior!!!',)
				print ('{} is Contacting with {}'.format(name, contactName))
				good = False
	if good:	'Connectivity is Good'
	print('\n')

def _test():
	file = r'C:\Users\landisb\Workspace\AssemblyModels\BasicContact\Coarse\ContactWithCartilage.xml'
	Assembly = ReadConnectivity(file)

	for part in Assembly.values():
		print(part)
		# print part.name
		if part.name == 'FemoralCartilage':
			for i,t in part.Ties.iteritems():
				print(i,t)


if __name__ == '__main__':
	print('\n')
	_test()
</pre></body></html>