# 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.
#
# process: internal

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

import apex
import math


def main(dict={}):
    from apex.construct import Point3D, Point2D

    _selected = apex.selection.getCurrentSelection()

    myModel = apex.currentModel()

    matchFaces = dict["matchNumberOfFaces"]
    if matchFaces.upper() == "TRUE":
        matchFaces = True
    else:
        matchFaces = False

    volumePCT = float(dict["volumeTolerance"])
    volumeTol = volumePCT/100.0
    if volumeTol <= 0.0: volumeTol = 0.01
    print("Volume Tolerance: "+str(volumeTol))

    print("Solids selected: "+str(_selected.len()))

    if _selected.len() == 0:
        if "test" in dict.keys():
            _selected = dict["test"]
        else:
            print("No solids selected!")
            return

    testSolids = apex.entityCollection()
    for sel in _selected:
        if sel.getEntityType() == apex.EntityType.Solid:
            testSolids.append(sel)

    if testSolids.len() == 0:
        print("Selected items were not solids!")
        return

    testSolidData = {}
    for solid in testSolids:
        faces = solid.getFaces()
        totalArea = 0.0
        for face in faces: totalArea += face.getArea()
        testSolidData[solid.getParent().getName()+"-"+solid.getName()] = {"volume":solid.getVolume(), "volume fraction":solid.getVolume()*volumeTol, "total faces":solid.getFaces().len(), "face area":totalArea}

    parts = myModel.getParts(True)
    allSolids = apex.entityCollection()
    for part in parts:
        allSolids += part.getSolids()

    similarSolids = {}
    for s in testSolids:
        similarSolids[s.getParent().getName()+"-"+s.getName()] = []

    for solid in allSolids:
        if solid.getParent().getName()+"-"+solid.getName() in testSolidData.keys(): continue

        vol    = solid.getVolume()
        nFaces = solid.getFaces().len()

        for s in testSolids:
            data = testSolidData[s.getParent().getName()+"-"+s.getName()]
            if abs(vol - data["volume"]) > data["volume fraction"]: continue

            if matchFaces and nFaces != data["total faces"]: continue

            similarSolids[s.getParent().getName()+"-"+s.getName()].append(solid)
            break


    for s in testSolids:
        print(s.getParent().getName()+"-"+s.getName())
        print("** similar solids: "+str(len(similarSolids[s.getParent().getName()+"-"+s.getName()])))

        if len(similarSolids[s.getParent().getName()+"-"+s.getName()]) > 0:
            similarSolids[s.getParent().getName()+"-"+s.getName()].append(s)
        else:
            continue

        _target = apex.entityCollection()
        _target.appendList(similarSolids[s.getParent().getName()+"-"+s.getName()])
        newPart = myModel.createPart("_similar_")
        apex.reparent( parent = newPart, target = _target )





