# 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  (1.2a)                  Larry Pearce

import apex

import math


def calcDistance(n1, n2):
    dx = n2.getX() - n1.getX()
    dy = n2.getY() - n1.getY()
    dz = n2.getZ() - n1.getZ()

    dist = dx**2 + dy**2 + dz**2
    if dist > 0.0: dist = math.sqrt(dist)

    return dist


def main(dict={}):

    ret_dict = {}

    ret_dict["dataDefined"] = 0

    apex.disableShowOutput()
    _selected = apex.selection.getCurrentSelection()

    if _selected.len() == 0: return ret_dict

    elmTopoNames = ["Bar2", "Tria3", "Tria6", "Quad4", "Quad8", "Tet4", "Tet10", "Wedge6", "Wedge15", "Hex8", "Hex20"]
    meshBodyTypes = [apex.EntityType.SolidMesh, apex.EntityType.SurfaceMesh, apex.EntityType.CurveMesh, apex.EntityType.HexMesh]

    myModel = apex.currentModel()

    selParts  = apex.entityCollection()
    selBodies = apex.entityCollection()
    for sel in _selected:
        if sel.getEntityType() == apex.EntityType.Part:
            selParts.append(sel)
        elif sel.getEntityType() in meshBodyTypes:
            selBodies.append(sel)

    if selParts.len() + selBodies.len() == 0: return ret_dict

    minDist = 999999999.0
    maxDist = 0.0
    minDistElm = maxDistElm = None

    meshBodies = apex.entityCollection()
    for part in selParts:
        meshBodies += part.getMeshes()
        for body in meshBodies:
            elms = body.getElements()
            for elm in elms:
                elmEdges = elm.getEdges()
                for edge in elmEdges:
                    edgeNodes = edge.getNodes()
                    dist = calcDistance(edgeNodes[0], edgeNodes[1])
                    if dist < minDist:
                        minDist    = dist
                        minDistElm = elm
                        minDistPart = part
                    if dist > maxDist:
                        maxDist    = dist
                        maxDistElm = elm
                        maxDistPart = part

    for body in selBodies:
        part = body.getParent()
        elms = body.getElements()
        for elm in elms:
            elmEdges = elm.getEdges()
            for edge in elmEdges:
                edgeNodes = edge.getNodes()
                dist = calcDistance(edgeNodes[0], edgeNodes[1])
                if dist < minDist:
                    minDist    = dist
                    minDistElm = elm
                    minDistPart = part
                if dist > maxDist:
                    maxDist    = dist
                    maxDistElm = elm
                    maxDistPart = part


    colorRGB = apex.ColorRGB(255, 255, 255)
    minDistElm.highlight(colorRGB, 2, 3)

    nodes = minDistElm.getNodes()
    x = y = z = 0.0
    for node in nodes:
        x += node.getX()
        y += node.getY()
        z += node.getZ()
    x = x/nodes.len()
    y = y/nodes.len()
    z = z/nodes.len()

    apex.display.displayText(text=str(minDistElm.getId()), textLocation=apex.Coordinate(x, y, z), graphicsFontColor=colorRGB, graphicsFontSize=14)

    ret_dict["dataDefined"]      = 1
    ret_dict["minEdgeLength"]    = minDist
    ret_dict["minLengthElm"]     = minDistElm.getId()
    ret_dict["minDistPart"]      = minDistPart.getName()
    ret_dict["minLengthElmTopo"] = elmTopoNames[minDistElm.getTopology()]
    ret_dict["maxEdgeLength"]    = maxDist
    ret_dict["maxLengthElm"]     = maxDistElm.getId()
    ret_dict["maxDistPart"]      = maxDistPart.getName()
    ret_dict["maxLengthElmTopo"] = elmTopoNames[maxDistElm.getTopology()]

    return ret_dict


def clearHighlights(dict={}):
    apex.disableShowOutput()
    myModel = apex.currentModel()
    allElms = myModel.getElements()

    for elm in allElms:
        elm.clearHighlight()

    apex.display.clearAllGraphicsText()




