# 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.0)                    Larry Pearce

import apex


def main(dict={}):
    apex.setScriptUnitSystem(unitSystemName = r'''in-slinch-s-lbf''')
    myModel = apex.currentModel()

    closeTol = float(dict["closeTol"])
    numNear  = 10

    print("Close Tol: "+str(closeTol))
    print("numNear: "+str(numNear))

    selectedStuff = apex.selection.getCurrentSelection()

    selectedVerts = apex.entityCollection()
    for item in selectedStuff:
        if item.getEntityType() == apex.EntityType.Vertex:
            selectedVerts.append(item)
        else:
            selectedVerts += item.getVertices()

    numSelected = selectedVerts.len()
    if numSelected == 0 and "test" in dict.keys():
        vertIds = []
        verts    = apex.entityCollection()
        parts = myModel.getParts(True)
        for part in parts:
            curves = part.getCurves()
            for curve in curves:
                edges = curve.getEdges()
                for edge in edges: verts += edge.getVertices()
            surfs = part.getSurfaces()
            for surf in surfs:
                faces = surf.getFaces()
                for face in faces: verts += face.getVertices()
        for vert in verts:
           if vert.getId() in vertIds: continue
           selectedVerts.append(vert)
           vertIds.append(vert.getId())
        numSelected = selectedVerts.len()
    print("Selected Verts: "+str(numSelected))

    if numSelected < 2:
        print("Must selected at least 2 vertices!")
        return

    vertSearch = apex.utility.ProximitySearch()
    allVerts = []
    vertData = {}
    for vert in selectedVerts:
        nodes = vert.getNodes()
        if nodes.len() == 0: continue # must be a node at the vertex to create a connector
        allVerts.append(vert)
        vertData[vert.getIndex()] = False
        vertSearch.insert(vert.asIPhysical())

    #print(allVerts)
    for vert in allVerts:
        if vertData[vert.getIndex()]: continue
        nearestObjects = vertSearch.findNearestObjects(vert.getLocation(), numNear)
        nearObjects = nearestObjects.foundObjects()
        nearDist    = nearestObjects.getDistances()
        foundObject = False
        #print(nearDist)
        #print(numNear)
        numNear = nearObjects.len()
        #print(numNear)
        for i in range(numNear):
            #print(i)
            if nearDist[i] > closeTol: continue
            vert2 = nearObjects[i].asEntity()
            b1 = vert.getBody()
            b2 = vert2.getBody()
            p1 = b1.getParent()
            p2 = b2.getParent()
            if p1.getName() == p2.getName() and b1.getName() == b2.getName():
                continue
            foundObject = True
        if foundObject:
            _endPoint1 = apex.construct.createLocationByEntity(entity = vert)
            _endPoint2 = apex.construct.createLocationByEntity(entity = vert2)

            connectorProps = apex.attribute.createConnectorProperties(
                stiffness = 0.0,
                damping = 0.0,
                translationalStiffnessX = 0.0,
                translationalStiffnessY = 0.0,
                translationalStiffnessZ = 0.0,
                rotationalStiffnessX = 0.0,
                rotationalStiffnessY = 0.0,
                rotationalStiffnessZ = 0.0,
                translationalDampingX = 0.0,
                translationalDampingY = 0.0,
                translationalDampingZ = 0.0,
                rotationalDampingX = 0.0,
                rotationalDampingY = 0.0,
                rotationalDampingZ = 0.0,
                diameter = 0.0,
                linkMaterial = None)

            connector = apex.attribute.createConnector(
                name = "Connector",
                connectorType = apex.attribute.ConnectorType.RigidLink,
                connectorProperties = connectorProps,
                applicationMethod1 = apex.attribute.ApplicationMethod.Direct,
                applicationMethod2 = apex.attribute.ApplicationMethod.Direct,
                end1InterfacePoint = _endPoint1, 
                end2InterfacePoint = _endPoint2, 
                description = "")

            vertData[vert.getIndex()]  = True
            vertData[vert2.getIndex()] = True



