def handle_eclipses(self, expose_horizon=False, **kwargs):
        """
        Detect the triangles at the horizon and the eclipsed triangles, handling
        any necessary subdivision.

        :parameter str eclipse_method: name of the algorithm to use to detect
            the horizon or eclipses (defaults to the value set by computeoptions)
        :parameter str subdiv_alg: name of the algorithm to use for subdivision
            (defaults to the value set by computeoptions)
        :parameter int subdiv_num: number of subdivision iterations (defaults
            the value set by computeoptions)
        """

        eclipse_method = kwargs.get('eclipse_method', self.eclipse_method)
        horizon_method = kwargs.get('horizon_method', self.horizon_method)

        # Let's first check to see if eclipses are even possible at these
        # positions.  If they are not, then we only have to do horizon
        #
        # To do that, we'll take the conservative max_r for each object
        # and their current positions, and see if the separations are larger
        # than sum of max_rs
        possible_eclipse = False
        if len(self.bodies) == 1:
            if self.bodies[0].__class__.__name__ == 'Envelope':
                possible_eclipse = True
            else:
                possible_eclipse = False
        else:
            logger.debug("system.handle_eclipses: determining if eclipses are possible from instantaneous_maxr")
            max_rs = [body.instantaneous_maxr for body in self.bodies]
            # logger.debug("system.handle_eclipses: max_rs={}".format(max_rs))
            for i in range(0, len(max_rs)-1):
                for j in range(i+1, len(max_rs)):
                    proj_sep_sq = sum([(c[i]-c[j])**2 for c in (self.xs,self.ys)])
                    max_sep_ecl = max_rs[i] + max_rs[j]

                    if proj_sep_sq < (1.05*max_sep_ecl)**2:
                        # then this pair has the potential for eclipsing triangles
                        possible_eclipse = True
                        break

        if not possible_eclipse and not expose_horizon and horizon_method=='boolean':
            eclipse_method = 'only_horizon'

        # meshes is an object which allows us to easily access and update columns
        # in the meshes *in memory*.  That is meshes.update_columns will propogate
        # back to the current mesh for each body.
        meshes = self.meshes

        # Reset all visibilities to be fully visible to start
        meshes.update_columns('visiblities', 1.0)

        ecl_func = getattr(eclipse, eclipse_method)

        if eclipse_method=='native':
            ecl_kwargs = {'horizon_method': horizon_method}
        else:
            ecl_kwargs = {}

        logger.debug("system.handle_eclipses: possible_eclipse={}, expose_horizon={}, calling {} with kwargs {}".format(possible_eclipse, expose_horizon, eclipse_method, ecl_kwargs))

        visibilities, weights, horizon = ecl_func(meshes,
                                                  self.xs, self.ys, self.zs,
                                                  expose_horizon=expose_horizon,
                                                  **ecl_kwargs)

        # NOTE: analytic horizons are called in backends.py since they don't
        # actually depend on the mesh at all.

        # visiblilities here is a dictionary with keys being the component
        # labels and values being the np arrays of visibilities.  We can pass
        # this dictionary directly and the columns will be applied respectively.
        meshes.update_columns('visibilities', visibilities)

        # weights is also a dictionary with keys being the component labels
        # and values and np array of weights.
        if weights is not None:
            meshes.update_columns('weights', weights)

        return horizon
def handle_eclipses ( self , expose_horizon = False , ** kwargs ) : eclipse_method = kwargs . get ( 'eclipse_method' , self . eclipse_method ) horizon_method = kwargs . get ( 'horizon_method' , self . horizon_method ) possible_eclipse = False if len ( self . bodies ) == 1 : if self . bodies [ 0 ] . __class__ . __name__ == 'Envelope' : possible_eclipse = True else : possible_eclipse = False else : logger . debug ( "system.handle_eclipses: determining if eclipses are possible from instantaneous_maxr" ) max_rs = [ body . instantaneous_maxr for body in self . bodies ] for i in range ( 0 , len ( max_rs ) - 1 ) : for j in range ( i + 1 , len ( max_rs ) ) : proj_sep_sq = sum ( [ ( c [ i ] - c [ j ] ) ** 2 for c in ( self . xs , self . ys ) ] ) max_sep_ecl = max_rs [ i ] + max_rs [ j ] if proj_sep_sq < ( 1.05 * max_sep_ecl ) ** 2 : possible_eclipse = True break if not possible_eclipse and not expose_horizon and horizon_method == 'boolean' : eclipse_method = 'only_horizon' meshes = self . meshes meshes . update_columns ( 'visiblities' , 1.0 ) ecl_func = getattr ( eclipse , eclipse_method ) if eclipse_method == 'native' : ecl_kwargs = { 'horizon_method' : horizon_method } else : ecl_kwargs = { } logger . debug ( "system.handle_eclipses: possible_eclipse={}, expose_horizon={}, calling {} with kwargs {}" . format ( possible_eclipse , expose_horizon , eclipse_method , ecl_kwargs ) ) visibilities , weights , horizon = ecl_func ( meshes , self . xs , self . ys , self . zs , expose_horizon = expose_horizon , ** ecl_kwargs ) meshes . update_columns ( 'visibilities' , visibilities ) if weights is not None : meshes . update_columns ( 'weights' , weights ) return horizon
Detect the triangles at the horizon and the eclipsed triangles, handling
        any necessary subdivision.

        :parameter str eclipse_method: name of the algorithm to use to detect
            the horizon or eclipses (defaults to the value set by computeoptions)
        :parameter str subdiv_alg: name of the algorithm to use for subdivision
            (defaults to the value set by computeoptions)
        :parameter int subdiv_num: number of subdivision iterations (defaults
            the value set by computeoptions)