<commit_before>from copy import copy, deepcopy
from bezier_constraint_odd_solver import *
from bezier_constraint_even_solver import *

from tictoc import tic, toc

class EngineError( Exception ): pass
class NoControlPointsError( EngineError ): pass
class NoHandlesError( EngineError ): pass

systems = []
############################### Basic Engine #################################
class Engine:
	def init_engine( self, paths_info, boundary_index ):
		'''
		initialize the control points for multiple paths and make the default constraints
		boundary_index tells which path is the outside boundary
		'''
		self.boundary_index = boundary_index	
		self.all_controls = [ make_control_points_chain( path[u'cubic_bezier_chain'], path[u'closed'] ) for path in paths_info]
		self.all_constraints = [ make_constraints_from_control_points( controls, path[u'closed'] ) for controls, path in zip( self.all_controls, paths_info ) ]
		self.num_of_paths = len( self.all_controls )
		
		self.transforms = []
		self.handle_positions = []
		self.weight_function = 'shepard'
	
	def copy_engine( self, engine ):
		self.boundary_index = engine.boundary_index
		self.all_controls = engine.all_controls
		self.all_constraints = engine.all_constraints
		self.num_of_paths = engine.num_of_paths
		
		self.transforms = engine.transforms
		self.handle_positions = engine.handle_positions
		self.weight_function = engine.weight_function
	
	def transform_change( self, i, transform ):
		'''
		change the transform at the index i
		'''
		assert i in range( len( self.transforms ) )
		transform = asarray( transform )
		if len( transform ) == 2:
			transform = concatenate( ( transform, array( [[0, 0, 1]] ) ), axis=0 )
		assert transform.shape == (3,3)
		
		self.transforms[i] = transform
			
	def set_handle_positions( self, new_handle_positions, new_transforms = None ):
		'''
		Replaces the set of known handles with the positions and transforms
		in new_handle_positions, new_transforms.
		If 'new_transforms' is not specified or is None,
		all handles will be set to the identity transformation.
		'''
		
		assert new_transforms is None or len( new_transforms ) == len( new_handle_positions )
		
		## Set the new handle positions.
		self.handle_positions = asarray( new_handle_positions ).tolist()
		## Initialize all the transforms to the identity matrix.
		## NOTE: We don't directly use 'new_transforms' here, because they're
		##		 in a different format.
		self.transforms = [ identity(3) for i in range(len( new_handle_positions )) ]
		
		## Set the corresponding transformations.
		if new_transforms is not None:
			for i, transform in enumerate( new_transforms ):
				self.transform_change( i, transform )

	def set_weight_function( self, weight_function ):
		'''
		set weight_function
		'''
		if self.weight_function != weight_function:
			self.weight_function = weight_function
			self.precompute_configuration( ) 
	
	def get_weight_function( self ):
		'''
		gets weight_function
		'''
		return self.weight_function

	def get_engine_type( self ):
		'''
		gets engine_type
		'''
		return self.engine_type

	def compute_target_path( self, path_indices, all_vertices, transforms, all_weights ):
		'''
		compute the target curves for just one path.
		'''
		### 3 
		target_curves_per_path = []
		for indices in path_indices:
				
			## http://jameshensman.wordpress.com/2010/06/14/multiple-matrix-multiplication-in-numpy/
			As = dot( asarray(transforms).T, all_weights[ indices ].T ).T
			Bs = append( all_vertices[ indices ], ones( ( len( indices ), 1 ) ), axis = 1 )
			tps = sum(As*Bs[:,newaxis,:],-1)[:,:2]
			
			target_curves_per_path.append(tps)
		
		return target_curves_per_path

	def compute_deformed_path( self, solutions, all_ts ):
		'''
		compute all the points along the curves for just one path.
		'''
		deformed_curves_per_path = []
		for k, solution in enumerate(solutions):

			tps = dot( array([all_ts[k]**3, all_ts[k]**2, all_ts[k], ones(all_ts[k].shape)]).T, asarray( dot( M, solution ) ) )
			deformed_curves_per_path.append(tps)
			
		return deformed_curves_per_path	
	
	def constraint_change( self, path_index, joint_index, constraint ): pass
	def precompute_configuration( self ): pass
	def set_enable_arc_length( self, is_arc_enabled ): pass
	def get_enable_arc_length( self ): return False
	def set_iterations( self, whether ): pass
	def prepare_to_solve( self ): pass
	def solve_transform_change( self ): 
		raise NotImplementedError( "This is an abstract base class. Only call this on a subclass." )
	def compute_energy_and_maximum_distance( self ):
		'''
		compute the error between the skinning spline and the bbw_affected position.
		'''	
		all_controls, handle_positions, transforms = self.all_controls, self.handle_positions, self.transforms
		solutions = self.solutions
		boundary_index = self.boundary_index
		weight_function = self.weight_function
		
		num_samples = 100
		all_pts, all_ts, all_dts = [], [], []
		for control_pos in all_controls:
			pts, ts, dts = sample_cubic_bezier_curve_chain( control_pos, num_samples )
			all_pts.append( pts )
			all_ts.append( ts )
			all_dts.append( dts )
			
		all_vertices, all_weights, all_indices = compute_all_weights( all_pts, handle_positions, boundary_index, weight_function )
		
		all_pts, all_ts, all_dts = asarray( all_pts ), asarray( all_ts ), asarray( all_dts )
		
		energy, target_paths, distances = [], [], []
		for i in range( self.num_of_paths ):

			path_indices = all_indices[i]		
			path_pts, path_ts, path_dts = all_pts[i], all_ts[i], all_dts[i]
			path_lengths = asarray( [ map( mag, ( curve_pts[1:] - curve_pts[:-1] ) ) for curve_pts in path_pts ]).sum( axis=1 )
			
			target_path = self.compute_target_path( path_indices, all_vertices, transforms, all_weights )
			target_paths.append( target_path )
			
			deformed_path = self.compute_deformed_path( solutions[i], path_ts )			
 			energy.append( compute_error_metric( target_path, deformed_path, path_dts, path_lengths ) )
 			distances.append( compute_maximum_distances( target_path, deformed_path ) )
		
 		return energy, target_paths, distances

			
############################### Basic Engine End #################################

class FourControlsEngine(Engine) :
	'''
	- apply deformation to all control points
	'''
	
	def solve_transform_change( self ):
		all_controls, handle_positions, transforms = self.all_controls, self.handle_positions, self.transforms
		boundary_index, weight_function = self.boundary_index, self.weight_function

  		all_vertices, all_weights, all_indices = compute_all_weights_shepard( all_controls, handle_positions )
		if 'bbw' == weight_function:
 			
			all_endpoints = [ asarray([ [curve[0], curve[3]] for curve in path ]) for path in all_controls ] 			
 			vs, faces, boundary_edges, all_weights, all_maps = compute_all_weights_bbw( all_endpoints, handle_positions, boundary_index, customized = True )
			
			flatten_ctrls = flatten_paths( all_controls )[0]
			ctrl_vertices, ctrl_weights, ctrl_maps = barycentric_projection( vs, faces, boundary_edges, all_weights, flatten_ctrls )
			
			all_weights = asarray([ ctrl_weights[index] for index in ctrl_maps])
			
		self.all_vertices, self.all_weights, self.all_indices = all_vertices, all_weights, all_indices	
	
		result = []
		for path_indices in all_indices:
			path_controls = []
			for indices in path_indices:

				As = dot( asarray(transforms).T, all_weights[ indices ].T ).T
				Bs = append( all_vertices[ indices ], ones( ( len( indices ), 1 ) ), axis = 1 )
				#tps = sum(As*Bs[:,newaxis,:],-1)[:,:2]
				tps = asarray([ dot( A, B ) for A, B in zip( As, Bs ) ])
		
				path_controls.append(tps)
			result.append( path_controls )
		
		result = [ asarray(path)[:,:,:2] for path in result ]<commit_msg>bbw for naive approaches.<commit_after>from copy import copy, deepcopy
from bezier_constraint_odd_solver import *
from bezier_constraint_even_solver import *

from tictoc import tic, toc

class EngineError( Exception ): pass
class NoControlPointsError( EngineError ): pass
class NoHandlesError( EngineError ): pass

systems = []
############################### Basic Engine #################################
class Engine:
	def init_engine( self, paths_info, boundary_index ):
		'''
		initialize the control points for multiple paths and make the default constraints
		boundary_index tells which path is the outside boundary
		'''
		self.boundary_index = boundary_index	
		self.all_controls = [ make_control_points_chain( path[u'cubic_bezier_chain'], path[u'closed'] ) for path in paths_info]
		self.all_constraints = [ make_constraints_from_control_points( controls, path[u'closed'] ) for controls, path in zip( self.all_controls, paths_info ) ]
		self.num_of_paths = len( self.all_controls )
		
		self.transforms = []
		self.handle_positions = []
		self.weight_function = 'shepard'
	
	def copy_engine( self, engine ):
		self.boundary_index = engine.boundary_index
		self.all_controls = engine.all_controls
		self.all_constraints = engine.all_constraints
		self.num_of_paths = engine.num_of_paths
		
		self.transforms = engine.transforms
		self.handle_positions = engine.handle_positions
		self.weight_function = engine.weight_function
	
	def transform_change( self, i, transform ):
		'''
		change the transform at the index i
		'''
		assert i in range( len( self.transforms ) )
		transform = asarray( transform )
		if len( transform ) == 2:
			transform = concatenate( ( transform, array( [[0, 0, 1]] ) ), axis=0 )
		assert transform.shape == (3,3)
		
		self.transforms[i] = transform
			
	def set_handle_positions( self, new_handle_positions, new_transforms = None ):
		'''
		Replaces the set of known handles with the positions and transforms
		in new_handle_positions, new_transforms.
		If 'new_transforms' is not specified or is None,
		all handles will be set to the identity transformation.
		'''
		
		assert new_transforms is None or len( new_transforms ) == len( new_handle_positions )
		
		## Set the new handle positions.
		self.handle_positions = asarray( new_handle_positions ).tolist()
		## Initialize all the transforms to the identity matrix.
		## NOTE: We don't directly use 'new_transforms' here, because they're
		##		 in a different format.
		self.transforms = [ identity(3) for i in range(len( new_handle_positions )) ]
		
		## Set the corresponding transformations.
		if new_transforms is not None:
			for i, transform in enumerate( new_transforms ):
				self.transform_change( i, transform )

	def set_weight_function( self, weight_function ):
		'''
		set weight_function
		'''
		if self.weight_function != weight_function:
			self.weight_function = weight_function
			self.precompute_configuration( ) 
	
	def get_weight_function( self ):
		'''
		gets weight_function
		'''
		return self.weight_function

	def get_engine_type( self ):
		'''
		gets engine_type
		'''
		return self.engine_type

	def compute_target_path( self, path_indices, all_vertices, transforms, all_weights ):
		'''
		compute the target curves for just one path.
		'''
		### 3 
		target_curves_per_path = []
		for indices in path_indices:
				
			## http://jameshensman.wordpress.com/2010/06/14/multiple-matrix-multiplication-in-numpy/
			As = dot( asarray(transforms).T, all_weights[ indices ].T ).T
			Bs = append( all_vertices[ indices ], ones( ( len( indices ), 1 ) ), axis = 1 )
			tps = sum(As*Bs[:,newaxis,:],-1)[:,:2]
			
			target_curves_per_path.append(tps)
		
		return target_curves_per_path

	def compute_deformed_path( self, solutions, all_ts ):
		'''
		compute all the points along the curves for just one path.
		'''
		deformed_curves_per_path = []
		for k, solution in enumerate(solutions):

			tps = dot( array([all_ts[k]**3, all_ts[k]**2, all_ts[k], ones(all_ts[k].shape)]).T, asarray( dot( M, solution ) ) )
			deformed_curves_per_path.append(tps)
			
		return deformed_curves_per_path	
	
	def constraint_change( self, path_index, joint_index, constraint ): pass
	def precompute_configuration( self ): pass
	def set_enable_arc_length( self, is_arc_enabled ): pass
	def get_enable_arc_length( self ): return False
	def set_iterations( self, whether ): pass
	def prepare_to_solve( self ): pass
	def solve_transform_change( self ): 
		raise NotImplementedError( "This is an abstract base class. Only call this on a subclass." )
	def compute_energy_and_maximum_distance( self ):
		'''
		compute the error between the skinning spline and the bbw_affected position.
		'''	
		all_controls, handle_positions, transforms = self.all_controls, self.handle_positions, self.transforms
		solutions = self.solutions
		boundary_index = self.boundary_index
		weight_function = self.weight_function
		
		num_samples = 100
		all_pts, all_ts, all_dts = [], [], []
		for control_pos in all_controls:
			pts, ts, dts = sample_cubic_bezier_curve_chain( control_pos, num_samples )
			all_pts.append( pts )
			all_ts.append( ts )
			all_dts.append( dts )
			
		all_vertices, all_weights, all_indices = compute_all_weights( all_pts, handle_positions, boundary_index, weight_function )
		
		all_pts, all_ts, all_dts = asarray( all_pts ), asarray( all_ts ), asarray( all_dts )
		
		energy, target_paths, distances = [], [], []
		for i in range( self.num_of_paths ):

			path_indices = all_indices[i]		
			path_pts, path_ts, path_dts = all_pts[i], all_ts[i], all_dts[i]
			path_lengths = asarray( [ map( mag, ( curve_pts[1:] - curve_pts[:-1] ) ) for curve_pts in path_pts ]).sum( axis=1 )
			
			target_path = self.compute_target_path( path_indices, all_vertices, transforms, all_weights )
			target_paths.append( target_path )
			
			deformed_path = self.compute_deformed_path( solutions[i], path_ts )			
 			energy.append( compute_error_metric( target_path, deformed_path, path_dts, path_lengths ) )
 			distances.append( compute_maximum_distances( target_path, deformed_path ) )
		
 		return energy, target_paths, distances

			
############################### Basic Engine End #################################

class FourControlsEngine(Engine) :
	'''
	- apply deformation to all control points
	'''
	
	def solve_transform_change( self ):
		all_controls, handle_positions, transforms = self.all_controls, self.handle_positions, self.transforms
		boundary_index, weight_function = self.boundary_index, self.weight_function

  		all_vertices, all_weights, all_indices = compute_all_weights_shepard( all_controls, handle_positions )
		if 'bbw' == weight_function:
 			
			all_endpoints = [ asarray([ [curve[0], curve[3]] for curve in path ]) for path in all_controls ] 			
 			vs, faces, boundary_edges, all_weights, all_maps = compute_all_weights_bbw( all_endpoints, handle_positions, boundary_index, customized = True )
			
			flatten_ctrls = flatten_paths( all_controls )[0]
			ctrl_vertices, ctrl_weights, ctrl_maps = barycentric_projection( vs, faces, boundary_edges, all_weights, flatten_ctrls )
			
			all_weights = asarray([ ctrl_weights[index] for index in ctrl_maps])
		
		elif 'mvc' == weight_function:
			
			ctrl_vertices, ctrl_weights, ctrl_maps = compute_all_weights_mvc( all_controls, handle_positions )
			debugger()
			print 'hi mvc'
	
			
		self.all_vertices, self.all_weights, self.all_indices = all_vertices, all_weights, all_indices	
	
		result = []
		for path_indices in all_indices:
			path_controls = []
			for indices in path_indices:

				As = dot( asarray(transforms).T, all_weights[ indices ].T ).T
				Bs = append( all_vertices[ indices ], ones( ( len( indices ), 1 ) ), axis = 1 )
				#tps = sum(As*Bs[:,newaxis,:],-1)[:,:2]
				tps = asarray([ dot( A, B ) for A, B in zip( As, Bs ) ])
		
				path_controls.append(tps)
			result.append( path_controls )
		
		result = [ asarray(path)[:,:,:2] for path in result ]
{'fraction_non_alphanumeric': 0.11465781409601634, 'fraction_numerical': 0.004724208375893769, 'mean_word_length': 4.479188527457153, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4967071', 'n_tokens_mistral': 5650, 'n_tokens_neox': 4943, 'n_words': 1306}