<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 sys
import os


class SimulationPart:
	def __init__(self, name, file, material, Ties, Contact, mesh=None):
		self.name = name
		self.file = file
		if file.endswith('.stl'):	self.med = 'MED/{}'.format(file.replace('.stl', '.med'))
		else:						self.med=file
		self.mat = material
		self.mesh = mesh		# will put mesh data here
		self.Ties = Ties		# dictionary of name:multiplier for Ties
		self.Contact = Contact	# dictionary of name:multiplier for Contact by proxmity

	def __repr__(self):
		# return "{}, {}\t{}\n\tTies:{}\n\tContact:{}".format(self.name.capitalize(),self.mat,self.file,self.Ties,self.Contact)
		if self.mesh:
			return "{}, {}	MESHED\n	Ties:{}\n	Contact:{}".format(self.name.capitalize(), self.mat, self.Ties.keys(), self.Contact.keys())
		else:
			return "{}, {}	{}\n	Ties:{}\n	Contact:{}".format(self.name.capitalize(), self.mat, self.file, self.Ties.keys(), self.Contact.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)"""
	# try:
	tree = ET.ElementTree(file=filename)
	# except:
	# 	print '\n\n{} file is not a valid xml document.\n'.format(os.path.basename(filename))
	# 	sys.exit()
	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
		#
		#	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==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:							mult = 1.0
					ties[elem.tag] = {elemType: mult}
				elif elemType=='contains':	ties[elem.tag] = {elemType: elem.get('contains')}
				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':
					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:							mult = 1.0	# a larger value probably make more sense here
					contact[elem.tag] = {elemType: mult}
				elif elemType=='contains':			contact[elem.tag] = {elemType: elem.get('contains')}
				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':
						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:								mult = 1.0  # a larger value probably make more sense here
						contact[elem.tag] = {elemType: mult}
					elif elemType == 'contains':			contact[elem.tag] = {elemType: elem.get('contains')}
					else:									contact[elem.tag] = {elemType:None}
		assembly[part.tag] = SimulationPart(name, file, material, ties, contact)
	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.iteritems():
		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'

def CheckRedundancy(assembly):
	"""Verify that connections are listed for both parts
		and also that the types of connection are the same
		i.e. if PartA is connected by proximity to PartB, PartB will also be connected by proximity to PartA
		mostly used to determine if I should make groups two by two or one by one"""
	redundant = True
	for name, part in assembly.iteritems():
		for tiedName, tieType in part.Ties.iteritems():
			if part.Ties[tiedName].keys() != assembly[tiedName].Ties[name].keys():
				redundant = False
				break
		for contactName, connectType in part.Contact.iteritems():
			if part.Contact[contactName].keys() != assembly[contactName].Contact[name].keys():
				redundant = False
				break
	return redundant


def _test():
	# file = '/home/landisb/workspace/SofaTesting/Meshes/STL/Decimate/Connectivity.xml'
	file = '/home/landisb/PycharmProjects/Data/BasicScriptTest/Decimate/Connectivity.xml'
	Assembly = ReadConnectivity(file)

	# for part in Assembly.values():
	# 	print part


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