# coding: utf-8
#
# Copyright © 2020 MSC.Software Corporation
#  
# Permission to use Scripts
#  
# Permission is granted to MSC.Software customers with valid licenses of the MSC Apex™ software 
# to use script files posted on this page (collectively “Scripts”) solely for customers’ own authorized 
# internal use in conjunction with licensed use of the MSC Apex software.  
# No other use is permitted.  No license to MSC Apex or other software is granted under this Permission.
#  
# SCRIPTS ARE PROVIDED ON AN "AS-IS" BASIS, WITH NO WARRANTIES OF ANY KIND.  USE OF THE SCRIPTS IS AT CUSTOMER'S SOLE RISK.
#  
# IN NO EVENT SHALL MSC.SOFTWARE CORPORATION, ITS AFFILIATES, SUBSIDIARIES, SUPPLIERS, AGENTS, REPRESENTATIVES OR EMPLOYEES BE LIABLE FOR ANY 
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, TORT, 
# STRICT LIABILITY, OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION USE OF THE SCRIPTS, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
#  
# Customer shall indemnify, defend and hold MSC.Software Corporation, its affiliates, subsidiaries, suppliers, agents, 
# employees or representatives (collectively, “Indemnified Parties”) harmless from and against any third-party claims 
# brought against Indemnified Parties rising out of or in connection with Customer’s use of the Scripts.
#

# Author: Larry Pearce
# Revised by: Larry Pearce
# Revision History
# Date         Change                                 By
# 2020-10-12   Original code (2.0)                    Larry Pearce


import apex
from apex.construct import Point3D, Point2D
import sys
import auClearHighlights


def getShortEdges(selBodies, shortLength):
	minShortLength = 1.e20
	maxShortLength = -1.0
	
	numShortEdges = 0
	
	minLengthEdge = None
	
	shortEdges = apex.entityCollection()
	for sel in selBodies:
		edges = sel.getEdges()
		for edge in edges:
			if edge.getLength() <= shortLength:
				if edge.getLength() <= minShortLength:
					minShortLength = edge.getLength()
					minLengthEdge = edge
				if edge.getLength() >= maxShortLength:
					maxShortLength = edge.getLength()
				numShortEdges += 1
				shortEdges.append(edge)

	retData = {}
	retData["numShortEdges"]  = numShortEdges
	retData["minShortLength"] = minShortLength
	retData["maxShortLength"] = maxShortLength
	retData["minLengthEdge"]  = minLengthEdge
	retData["shortEdges"]     = shortEdges

	return retData


def highlightShortEdges(selBodies, shortLength, shortEdgeColor, shortestEdgeColor, fontSize):
	data = getShortEdges(selBodies, shortLength)
	
	print("Short Edge Length for testing: "+str(shortLength))
	print("Short Edges Found: "+str(data["numShortEdges"]))
	if data["numShortEdges"] > 0:
		print("Shortest Edge Length: "+str(data["minShortLength"]))
		print("Max Shortest Edge Length: "+str(data["maxShortLength"]))
	
	for edge in data["shortEdges"]:
		edge.highlight(colorRGB = shortEdgeColor, lineWidth = 3, pointSize = 1)

	if data["minLengthEdge"] != None:
		data["minLengthEdge"].clearHighlight()
		data["minLengthEdge"].highlight(colorRGB = shortestEdgeColor, lineWidth = 3, pointSize = 1)
		mp = data["minLengthEdge"].getMidPoint()
		apex.display.displayText(text="minEdge", textLocation=mp, graphicsFontColor=shortestEdgeColor, graphicsFontSize=fontSize)


def suppressShortEdges(selBodies, shortLength):
	dictionary = {}
	dictionary["entities"] = "edges"
	auClearHighlights.main(dictionary)
	data = getShortEdges(selBodies, shortLength)
	
	if data["numShortEdges"] == 0: return
	
	print("Short Edge Length for testing: "+str(shortLength))
	print("Short Edges Found: "+str(data["numShortEdges"]))
	if data["numShortEdges"] > 0:
		print("Shortest Edge Length: "+str(data["minShortLength"]))
		print("Max Shortest Edge Length: "+str(data["maxShortLength"]))

	suppressEdges(data["shortEdges"])


def suppressEdges(edgesToSuppress):
#	for edge in edgesToSuppress:
#		_target = apex.entityCollection()
#		_target.append(edge)
#		apex.geometry.suppressOnly(
#            target = _target,
#             maxEdgeAngle = 1.000000000000000e+01,
#             maxFaceAngle = 5.000000000000000,
#             keepVerticesAtCurvatureChange = False,
#             cleanupTol = 3.937007874015748e-02,
#             forceSuppress = True)
	apex.geometry.suppressOnly(
            target = edgesToSuppress,
             maxEdgeAngle = 1.000000000000000e+01,
             maxFaceAngle = 5.000000000000000,
             keepVerticesAtCurvatureChange = False,
             cleanupTol = 3.937007874015748e-02,
             forceSuppress = True)


def getSmallFaces(selBodies, smallArea):
	minSmallArea   = 1.e20
	maxSmallArea   = -1.0
	
	numSmallFaces = 0
	
	minAreaFace   = None
	
	smallFaces = apex.entityCollection()
	for sel in selBodies:
		faces = sel.getFaces()
		for face in faces:
			if face.getArea() <= smallArea:
				if face.getArea() <= minSmallArea:
					minSmallArea = face.getArea()
					minAreaFace = face
				if face.getArea() >= maxSmallArea:
					maxSmallArea = face.getArea()
				numSmallFaces += 1
				smallFaces.append(face)

	retData = {}
	retData["numSmallFaces"] = numSmallFaces
	retData["minSmallArea"]  = minSmallArea
	retData["maxSmallArea"]  = maxSmallArea
	retData["minAreaFace"]   = minAreaFace
	retData["smallFaces"]    = smallFaces

	return retData


def suppressSmallFaces(selBodies, smallArea):
	data = getSmallFaces(selBodies, smallArea)
	
	if data["numSmallFaces"] == 0: return
	
	print("Small Face Area for testing: "+str(smallArea))
	print("Small Faces Found: "+str(data["numSmallFaces"]))
	if data["numSmallFaces"] > 0:
		print("Smallest Area: "+str(data["minSmallArea"]))
		print("Max Smallest Face Area: "+str(data["maxSmallArea"]))
	
	edges = apex.entityCollection()
	for face in data["smallFaces"]:
		edges += face.getEdges()

	suppressEdges(edges)


def highlightSmallFaces(selBodies, smallArea, smallFaceColor, smallestFaceColor, fontSize):
	data = getSmallFaces(selBodies, smallArea)
	
	print("Small Face Area for testing: "+str(smallArea))
	print("Small Faces Found: "+str(data["numSmallFaces"]))
	if data["numSmallFaces"] > 0:
		print("Smallest Area: "+str(data["minSmallArea"]))
		print("Max Smallest Face Area: "+str(data["maxSmallArea"]))
	
	for face in data["smallFaces"]:
		face.highlight(colorRGB = smallFaceColor, lineWidth = 2, pointSize = 1)
	
	if data["minAreaFace"] != None:
		data["minAreaFace"].clearHighlight()
		data["minAreaFace"].highlight(colorRGB = smallestFaceColor, lineWidth = 2, pointSize = 1)
		mp = data["minAreaFace"].getCentroid()
		apex.display.displayText(text="minFace", textLocation=mp, graphicsFontColor=smallestFaceColor, graphicsFontSize=fontSize)


def main(dict={}):
	#apex.disableShowOutput()

	#unitSystem = r'''in-slinch-s-lbf'''
	#apex.setScriptUnitSystem(unitSystemName = unitSystem)

	shortEdgeColor    = apex.ColorRGB(255, 255, 255)  # white
	smallFaceColor    = apex.ColorRGB(255, 255, 255)  # white
	shortestEdgeColor = apex.ColorRGB(255, 50, 50)   # hopefully red
	smallestFaceColor = apex.ColorRGB(255, 50, 50)   # hopefully red
	shortLength = float(dict["shortEdgeLength"])
	smallArea   = float(dict["smallFaceArea"])
	mode        = dict["mode"]
	fontSize = 14

	#shortLength = 0.1
	#smallArea   = 0.1
	
	myModel = apex.currentModel()
	parts = myModel.getParts(True)
	
	selBodies = apex.entityCollection()
	
	_selected = apex.selection.getCurrentSelection()
	geoms = apex.entityCollection()
	if _selected.len() == 0:
		for part in parts:
			surfs = part.getSurfaces()
			geoms.extend(surfs)
			solids = part.getSolids()
			geoms.extend(solids)
			for geom in geoms:
				if geom.getVisibility() == 1:
					selBodies.append(geom)
		print("Processing "+str(selBodies.len())+" visible geometry bodies ...")
	else:
		for sel in _selected:
			if sel.getEntityType() == apex.EntityType.Surface:
				selBodies.append(sel)
			elif sel.getEntityType() == apex.EntityType.Solid:
				selBodies.append(sel)
		print("Processing "+str(selBodies.len())+" selected geometry bodies ...")
	
	if selBodies.len() == 0: return
	
	minShortLength = 1.e20
	minSmallArea   = 1.e20
	
	maxShortLength = -1.0
	maxSmallArea   = -1.0
	
	numShortEdges = 0
	numSmallFaces = 0
	
	minLengthEdge = None
	minAreaFace   = None
	
	if mode == "Highlight Short Edges": highlightShortEdges(selBodies, shortLength, shortEdgeColor, shortestEdgeColor, fontSize)
	if mode == "Highlight Small Faces": highlightSmallFaces(selBodies, smallArea, smallFaceColor, smallestFaceColor, fontSize)
	if mode == "Suppress Short Edges":   suppressShortEdges(selBodies, shortLength)
	if mode == "Suppress Small Faces":   suppressSmallFaces(selBodies, smallArea)
	

