# Creates midsurfaces with offset from only the outer faces of tube solids.
# Intended for making surfacing operations on welded structures easier.

import apex
from apex.construct import Point3D, Point2D

def main(dict={}):

	model_1 = apex.currentModel()

	Solids = apex.selection.getCurrentSelection()

#	print(len(Solids))

	solidCentroid = apex.Coordinate()

	for solid in Solids:
		
#		print(solid)
		
		# solidFaces = apex.EntityCollection()
		externalFaces = apex.EntityCollection()
		
		#get solid faces
		solidFaces = solid.getFaces()
		
#		print(len(solidFaces))
		
		solidCentroid = solid.getCentroid()
		
#		print("Centroid", solidCentroid)
		
		faceColl = apex.geometry.FaceCollection()

		for face in solidFaces:
			# find closest point to solid controid on face
			result = face.evaluateClosestLocation(solidCentroid)

			# find vector from solid centroid to point
			centroidVector = result.getVector()
#			print("Centroid vector ", centroidVector.getX(), centroidVector.getY(), centroidVector.getZ())
#			print("Length", centroidVector.getLength())
			
			# Create temp point (just for testing)
			#apex.geometry.createPointXYZ(result.getClosestLocation().getX(), result.getClosestLocation().getY(), result.getClosestLocation().getZ())
			
			# find surface normal at this point
			res = face.evaluatePointOnFace(result.getClosestLocation())
			faceNormal = face.evaluateNormal(res.u, res.v)
			
#			print("Face Normal ", faceNormal.getX(), faceNormal.getY(), faceNormal.getZ())
			
			# Round face vector to make numerical zero values actually zero
			xx = round(faceNormal.getX(), 3)
			yy = round(faceNormal.getY(), 3)
			zz = round(faceNormal.getZ(), 3)
			
			faceNormal.setX(xx)
			faceNormal.setY(yy)
			faceNormal.setZ(zz)
			
#			print("Rounded face normal ", xx, yy, zz)
			
			# Normalise and round centroid vector
			xx = centroidVector.getX()/centroidVector.getLength()
			yy = centroidVector.getY()/centroidVector.getLength()
			zz = centroidVector.getZ()/centroidVector.getLength()
			
			centroidVector.setX(round(xx, 3))
			centroidVector.setY(round(yy, 3))
			centroidVector.setZ(round(zz, 3))
			
#			print("Normalised centroid vector ", centroidVector.getX(), centroidVector.getY(), centroidVector.getZ())
			
			# If the centroid-to-face vector and the face normal vector are the same, then this is an external faceNormal
			# Note that for cases where there happens to be a hole in the face at the expected closest location, this method won't work...
			# Maybe find angle between vectors?  If less than 90°, is good?
			if centroidVector.getX() == faceNormal.getX() and centroidVector.getY() == faceNormal.getY() and centroidVector.getZ() == faceNormal.getZ():
				
#				print("*******Created Point*******")
#				apex.geometry.createPointXYZ(result.getClosestLocation().getX(), result.getClosestLocation().getY(), result.getClosestLocation().getZ())
			
				faceColl.append(face)
				
#		print(len(faceColl))

		offset = float(dict["offset"])
					
		# create surface
		result = apex.geometry.createMidSurfaceFixedOffset(
			target = faceColl,
			oneHalf = False,
			offsetDistance = offset
			)
