def validateNode(node, nodeAbsPath, hierarchyStepSize, extension):
    hrcFile = node + ".hrc"
    hrc = None
    if not os.path.isfile(nodeAbsPath + "/" + hrcFile):
        # Check if there is data in this node in Octtree A (we check if the HRC file for this node exist)
        raise Exception(nodeAbsPath + "/" + hrcFile + " could not be read")
    hrc = utils.readHRC(nodeAbsPath + "/" + hrcFile, hierarchyStepSize)
    for level in range(hierarchyStepSize + 1):
        hrcLevel = hrc[level]
        for i in range(len(hrcLevel)):
            hrcNumPoints = hrcLevel[i]
            if hrcNumPoints:
                (childNode, isFile) = utils.getNodeName(level, i, node, hierarchyStepSize, extension)
                childNodeAbsPath = nodeAbsPath + "/" + childNode
                if not os.path.exists(childNodeAbsPath):
                    print "Error: could not find ", childNodeAbsPath
                    raise Exception(node + " in " + nodeAbsPath + " is not correct")
                if isFile:
                    fNumPoints = utils.getPCFileDetails(childNodeAbsPath)[0]
                    if hrcNumPoints != fNumPoints:
                        print "Error: number of points in HRC (" + str(
                            hrcNumPoints
                        ) + ") != number of points in file (" + str(fNumPoints) + ") in " + childNodeAbsPath
                else:
                    validateNode(node + childNode, childNodeAbsPath, hierarchyStepSize, extension)
def getNames(node, hierarchyStepSize, data, extension):
    names = []
    for level in range(hierarchyStepSize + 2):
        if level < (hierarchyStepSize + 1):
            for i in range(len(data[level])):
                if data[level][i]:
                    names.append(utils.getNodeName(level, i, node, hierarchyStepSize, extension)[0])
    return names
def joinNode(node, nodeAbsPathA, nodeAbsPathB, nodeAbsPathO, hierarchyStepSize, extension, cmcommand):
    hrcFile = node + '.hrc'
    hrcA = None
    if os.path.isfile(nodeAbsPathA + '/' + hrcFile):
        # Check if there is data in this node in Octtree A (we check if the HRC file for this node exist)
        hrcA = utils.readHRC(nodeAbsPathA + '/' + hrcFile, hierarchyStepSize)

    hrcB = None
    if os.path.isfile(nodeAbsPathB + '/' + hrcFile):
        # Check if there is data in this node in Octtree B (we check if the HRC file for this node exist)
        hrcB = utils.readHRC(nodeAbsPathB + '/' + hrcFile, hierarchyStepSize)
    
    if hrcA != None and hrcB != None:
        utils.shellExecute('mkdir -p ' + nodeAbsPathO)
        # If both Octtrees A and B have data in this node we have to merge them
        hrcO = utils.initHRC(hierarchyStepSize)
        for level in range(hierarchyStepSize+2):
            numChildrenA = len(hrcA[level])
            numChildrenB = len(hrcB[level])
            numChildrenO = max((numChildrenA, numChildrenB))
            if level < (hierarchyStepSize+1):
                for i in range(numChildrenO):
                    hasNodeA = (i < numChildrenA) and (hrcA[level][i] > 0)
                    hasNodeB = (i < numChildrenB) and (hrcB[level][i] > 0)
                    (childNode, isFile) = utils.getNodeName(level, i, node, hierarchyStepSize, extension)
                    if hasNodeA and hasNodeB:
                        hrcO[level].append(hrcA[level][i] + hrcB[level][i])
                        #merge lAZ or folder (iteratively)
                        if isFile:
                            utils.shellExecute('lasmerge -i ' +  nodeAbsPathA + '/' + childNode + ' ' +  nodeAbsPathB + '/' + childNode + ' -o ' + nodeAbsPathO + '/' + childNode)
                            #We now need to set the header of the output file as the input files (lasmerge will have shrink it and we do not want that
                            fixHeader(nodeAbsPathA + '/' + childNode, nodeAbsPathO + '/' + childNode)
                        else:
                            joinNode(node + childNode, nodeAbsPathA + '/' + childNode, nodeAbsPathB + '/' + childNode, nodeAbsPathO + '/' + childNode, hierarchyStepSize, extension, cmcommand)
                    elif hasNodeA:
                        #mv / cp
                        hrcO[level].append(hrcA[level][i])
                        utils.shellExecute(cmcommand + nodeAbsPathA + '/' + childNode + ' ' + nodeAbsPathO + '/' + childNode)
                    elif hasNodeB:
                        #mv / cp
                        hrcO[level].append(hrcB[level][i])
                        utils.shellExecute(cmcommand + nodeAbsPathB + '/' + childNode + ' ' + nodeAbsPathO + '/' + childNode)
                    else:
                        hrcO[level].append(0)
            else:
                hrcO[level] = list(numpy.array(hrcA[level] + ([0]*(numChildrenO - numChildrenA))) + numpy.array(hrcB[level] + ([0]*(numChildrenO - numChildrenB))))            
        # Write the HRC file
        utils.writeHRC(nodeAbsPathO + '/' + hrcFile, hierarchyStepSize, hrcO)
    elif hrcA != None:
        # Only Octtree A has data in this node. We can directly copy it to the output Octtree
        utils.shellExecute(cmcommand + nodeAbsPathA + ' ' + nodeAbsPathO)
    elif hrcB != None:
        # Only Octtree B has data in this node. We can directly copy it to the output Octtree
        utils.shellExecute(cmcommand + nodeAbsPathB + ' ' + nodeAbsPathO)