<commit_before>#include "detect_stones.hpp"
#include "overwrittenOpenCV.hpp"

namespace Go_Scanner {

using namespace cv;
using namespace std;

//  Returns the size of a 45(left headed) or 135(right headed) line within a circle,
//  starting from any point within that circle
//  mainly used to get the diameters of the stones.
//  This functin also provides the Midpoint of that line.
int getStoneDistanceAndMidpoint(const Mat& warpedImgGray, int x, int y, lineheading heading, Point2i& midpointLine)
{

    int width = warpedImgGray.cols;
    int height = warpedImgGray.rows;

    int d1=0, d2=0, distance, xTmp1, yTmp1, xTmp2, yTmp2;

    if(heading == RIGHT)
    {
        xTmp1 = x;
        yTmp1 = y;
        while (xTmp1 > 0 && xTmp1 < width
            && yTmp1 > 0 && yTmp1 < height
            && warpedImgGray.at<uchar>(yTmp1,xTmp1) < 50)
        {
            //runs to bottom left
            xTmp1 -= 1;
            yTmp1 += 1;
            d1++;
        }

        xTmp2 = x;
        yTmp2 = y;
        while(xTmp2 > 0 && xTmp2 < width
            && yTmp2 > 0 && yTmp2 < height
            && warpedImgGray.at<uchar>(yTmp2,xTmp2) < 50)
        {
            //runs to top right
            xTmp2 += 1;
            yTmp2 -= 1;
            d2++;
        }
    }
    else //heading is left
    {

        xTmp1 = x;
        yTmp1 = y;
        while(xTmp1 > 0 && xTmp1 < width
            && yTmp1 > 0 && yTmp1 < height
            && warpedImgGray.at<uchar>(yTmp1,xTmp1) < 50)
        {
            //runs to top left
            xTmp1 -= 1;
            yTmp1 -= 1;
            d1++;
        }

        xTmp2 = x;
        yTmp2 = y;
        while(xTmp2 > 0 && xTmp2 < width
            && yTmp2 > 0 && yTmp2 < height
            && warpedImgGray.at<uchar>(yTmp2,xTmp2) < 50)
        {
            //runs to bottom right
            xTmp2 += 1;
            yTmp2 += 1;
            d2++;
        }
    }

    //distance of our line
    distance = d1 + d2;

    // midpoint of our first help line
    midpointLine.x = (xTmp1 + xTmp2) / 2;
    midpointLine.y = (yTmp1 + yTmp2) / 2;

    return distance;
}

void detectBlackStones(Mat& warpedImg, vector<Point2f> intersectionPoints, int board_size, map<Point2f, SgPoint, lesserPoint2f> to_board_coords, float stone_diameter, SgPointSet& stones, Mat& paintedWarpedImg)
{
    Mat tmp, warpedImgGray, canny;
    cvtColor(warpedImg, tmp, CV_RGB2GRAY);
    imshow("warped black stones", tmp);

    threshold(tmp, warpedImgGray, 85, 255, 0);

    //we morph the thresholded image to get rid of light spots from reflacting light on the black stones.
    int element_value = static_cast<int>(stone_diameter*0.38);
    Mat element = getStructuringElement(MORPH_ELLIPSE, Size(element_value, element_value));
    morphologyEx(warpedImgGray, warpedImgGray, MORPH_OPEN, element); // Apply the specified morphology operation

    //Draw circles around the intersections for easy detection of black stones
    for( size_t i = 0; i < intersectionPoints.size(); i++ )
    {
         Point center(cvRound(intersectionPoints[i].x), cvRound(intersectionPoints[i].y));
         int radius = cvRound(stone_diameter/2);
         // draw the circle outline
         circle(warpedImgGray, center, radius, Scalar(255), 2, 8, 0 );
    }

    imshow("Image for detecting black stones", warpedImgGray);

    for(size_t i=0; i < intersectionPoints.size(); i++)
    {
        auto& intersection_point = intersectionPoints[i];

        int x = cvRound(intersectionPoints[i].x);
        int y = cvRound(intersectionPoints[i].y);
        int distance, diameter45, diameter125;

        /**
        * Let's check if this is a stone :). We'll read out the diameters at 45 and 125 if they
        * are similar -> it's a stone.
        */

        if (warpedImgGray.at<uchar>(y,x) < 20)
        {

            /**
            *    first we produce a help line to get the diameters at 45 and 125.
            *    therefore we use the intersectionpoints.
            */
            Point2i midpointLine;
            distance = getStoneDistanceAndMidpoint(warpedImgGray, x, y, LEFT, midpointLine);

            // Get the Diameter for 125 degree
            Point2i midpoint125;
            diameter125 = getStoneDistanceAndMidpoint(warpedImgGray, midpointLine.x, midpointLine.y, RIGHT, midpoint125);

            // Get the Diameter for 45 degree
            Point2i midpoint45;
            diameter45 = getStoneDistanceAndMidpoint(warpedImgGray, midpoint125.x, midpoint125.y, LEFT, midpoint45);

            //it's a stone if the diameters are similiar, not to small and not to big.

            int min_stone_size;
            int max_stone_size;

            //9x9
            if(board_size <= 9)
            {
                min_stone_size = 30;
                max_stone_size = 80;
            }
            //13x13
            else if (board_size <= 13)
            {
                min_stone_size = 20;
                max_stone_size = 60;
            }
            //19x19 ++
            else
            {
                min_stone_size = 12;
                max_stone_size = 50;
            }

            if(diameter125+5 >= diameter45 && diameter125-5 <= diameter45 && diameter45 >= min_stone_size && diameter125 >= min_stone_size  && diameter45 <= max_stone_size && diameter125 <= max_stone_size)
            {
                //cout << "Black Stone ("<< x << ", "<< y << ")" << endl;

                stones.Include(to_board_coords[intersection_point]);

                circle( paintedWarpedImg,
                Point(midpoint125.x, midpoint125.y),
                (diameter125/2),
                Scalar(0, 255, 0), 0, 8, 0);
            }
        }
    }
}

void detectAllStones(Mat& warpedImg, vector<Point2f> intersectionPoints, map<Point2f, SgPoint, lesserPoint2f> to_board_coords, SgPointSet& stones, float stone_diameter, Mat& paintedWarpedImg)
{
    using namespace cv;
    Mat img;

    cvtColor(warpedImg, img, CV_RGB2GRAY);
    Canny(img, img, 100, 150, 3);

    // After canny we get a binary image, where all detected edges are white.
    // Dilate iterates over ervery pixel, and sets the pixel to the maximum pixel value within a circle around that pixel.
    // This leaves the areas black where no edges were detected and thus could contain a stone.
    int dilate_value = static_cast<int>(stone_diameter*0.8+0.5f);
    Mat element_dilate = getStructuringElement(MORPH_ELLIPSE, Size(dilate_value, dilate_value));
    dilate(img, img, element_dilate);
    imshow("after dilating", img);

    // Only the intersection points (later accessed by img.at<uchar>(y,x)) are relevant.
    // Erode looks for the minimum pixel value (black) within a circle around every pixel.
    // Because black pixels represent possible stones, if there is any black pixel within
    // a stone radius around an intersection then we have found a stone.
    int erode_value = static_cast<int>(stone_diameter*0.6+0.5f);
    Mat element_erode = getStructuringElement(MORPH_ELLIPSE, Size(erode_value, erode_value));
    // todo(mihi314) could be optimized by not using erode and instead only doing the erode operation at intersection points
    erode(img, img, element_erode);

    imshow("Image for detecting all stones", img);

    for(size_t i=0; i < intersectionPoints.size(); i++)
    {
        auto& intersection_point = intersectionPoints[i];

        int x = cvRound(intersection_point.x);
        int y = cvRound(intersection_point.y);

        /**
        * Let's check if this is a stone :).
        */
        if (img.at<uchar>(y,x) < 50)
        {
            //cout << "Stone ("<< x << ", "<< y << ")" << endl;
            stones.Include(to_board_coords[intersection_point]);

            circle( paintedWarpedImg,
            Point(cvRound(intersectionPoints[i].x), cvRound(intersectionPoints[i].y)),
            cvRound(stone_diameter/2.0f),
            Scalar(238, 238, 176), 0, 8, 0);

        }
    }
}

// Map pixel coordinates (intersection points) to board coordinates
// Begins at the left of the lowermost line and gradually moves the lines from left to right upwards.
//
// Preconditions:
// - The number of intersection points must match board_size * board_size!
// - Each line (or column if you want) must have exactly the same number of intersection points as the board_size value
// - It is required that the intersection points on a specific line all have almost equal y-values!
//   Thats the decision criteria for selecting the points on a given line.
map<Point2f, SgPoint, lesserPoint2f> getBoardCoordMapFor(vector<Point2f> intersectionPoints, int board_size)
{
    const auto& num_lines = board_size;

    // Sort points by their descending y-values to begin at the lowermost point
    sort(begin(intersectionPoints), end(intersectionPoints), [](const Point2f& left, const Point2f& right) { return left.y > right.y; });

    // Walk through each line from left to right and map a board coordinate to each point,
    // iteratively looks at the next batch (num_lines points) of intersection points
    map<Point2f, SgPoint, lesserPoint2f> to_board_coordinates;
    int line_idx = 1;
    auto begin_iter = begin(intersectionPoints);
    for (auto i = 0; i < num_lines; ++i, begin_iter += num_lines) {
        // Get the next num_lines points (these will be the points on the i-th line from the bottom)
        decltype(intersectionPoints) points_on_this_line;
        copy( begin_iter,
                   begin_iter+num_lines,
                   back_inserter(points_on_this_line));

        // Sort by ascending x values of the points
        sort(begin(points_on_this_line), end(points_on_this_line), [](const Point2f& left, const Point2f& right) { return left.x < right.x; });

        // Add an entry for each point on this line to the map
        int column_idx = 1;
        for (const auto& pt : points_on_this_line) {
            to_board_coordinates[pt] = SgPointUtil::Pt(column_idx++, line_idx);
        }

        ++line_idx;
    }

    return to_board_coordinates;
}

bool getStones(Mat srcWarpedImg, vector<Point2f> intersectionPoints, GoSetup& setup, int& board_size,Mat& paintedWarpedImg)
{
    // Calc the minimum distance between the first intersection point to all others
    // The minimum distance is approximately the diameter of a stone
    vector<float> distances;
    const auto& ref_point_min = *begin(intersectionPoints);
    for (const auto& point : intersectionPoints) {
        if (point != ref_point_min)
            distances.push_back(norm(point - ref_point_min));
    }
    auto approx_stone_diameter = *min_element(begin(distances), end(distances));

    cerr << "Board size: " << board_size << endl;

    // get map from intersection points to board coordinates (SgPoint)
    auto to_board_coords = getBoardCoordMapFor(intersectionPoints, board_size);

    // detect the stones!
    SgPointSet all_stones;
    detectAllStones(srcWarpedImg, intersectionPoints, to_board_coords, all_stones, approx_stone_diameter, paintedWarpedImg);

    SgPointSet black_stones;
    detectBlackStones(srcWarpedImg, intersectionPoints, board_size, to_board_coords, approx_stone_diameter, black_stones, paintedWarpedImg);
    setup.m_stones[SG_BLACK] = black_stones;
    setup.m_stones[SG_WHITE] = all_stones - black_stones;

    return true;
}

}<commit_msg>ref #79 - fixed last little value<commit_after>#include "detect_stones.hpp"
#include "overwrittenOpenCV.hpp"

namespace Go_Scanner {

using namespace cv;
using namespace std;

//  Returns the size of a 45(left headed) or 135(right headed) line within a circle,
//  starting from any point within that circle
//  mainly used to get the diameters of the stones.
//  This functin also provides the Midpoint of that line.
int getStoneDistanceAndMidpoint(const Mat& warpedImgGray, int x, int y, lineheading heading, Point2i& midpointLine)
{

    int width = warpedImgGray.cols;
    int height = warpedImgGray.rows;

    int d1=0, d2=0, distance, xTmp1, yTmp1, xTmp2, yTmp2;

    if(heading == RIGHT)
    {
        xTmp1 = x;
        yTmp1 = y;
        while (xTmp1 > 0 && xTmp1 < width
            && yTmp1 > 0 && yTmp1 < height
            && warpedImgGray.at<uchar>(yTmp1,xTmp1) < 50)
        {
            //runs to bottom left
            xTmp1 -= 1;
            yTmp1 += 1;
            d1++;
        }

        xTmp2 = x;
        yTmp2 = y;
        while(xTmp2 > 0 && xTmp2 < width
            && yTmp2 > 0 && yTmp2 < height
            && warpedImgGray.at<uchar>(yTmp2,xTmp2) < 50)
        {
            //runs to top right
            xTmp2 += 1;
            yTmp2 -= 1;
            d2++;
        }
    }
    else //heading is left
    {

        xTmp1 = x;
        yTmp1 = y;
        while(xTmp1 > 0 && xTmp1 < width
            && yTmp1 > 0 && yTmp1 < height
            && warpedImgGray.at<uchar>(yTmp1,xTmp1) < 50)
        {
            //runs to top left
            xTmp1 -= 1;
            yTmp1 -= 1;
            d1++;
        }

        xTmp2 = x;
        yTmp2 = y;
        while(xTmp2 > 0 && xTmp2 < width
            && yTmp2 > 0 && yTmp2 < height
            && warpedImgGray.at<uchar>(yTmp2,xTmp2) < 50)
        {
            //runs to bottom right
            xTmp2 += 1;
            yTmp2 += 1;
            d2++;
        }
    }

    //distance of our line
    distance = d1 + d2;

    // midpoint of our first help line
    midpointLine.x = (xTmp1 + xTmp2) / 2;
    midpointLine.y = (yTmp1 + yTmp2) / 2;

    return distance;
}

void detectBlackStones(Mat& warpedImg, vector<Point2f> intersectionPoints, int board_size, map<Point2f, SgPoint, lesserPoint2f> to_board_coords, float stone_diameter, SgPointSet& stones, Mat& paintedWarpedImg)
{
    Mat tmp, warpedImgGray, canny;
    cvtColor(warpedImg, tmp, CV_RGB2GRAY);
    imshow("warped black stones", tmp);

    threshold(tmp, warpedImgGray, 85, 255, 0);

    //we morph the thresholded image to get rid of light spots from reflacting light on the black stones.
    int element_value = static_cast<int>(stone_diameter*0.38);
    Mat element = getStructuringElement(MORPH_ELLIPSE, Size(element_value, element_value));
    morphologyEx(warpedImgGray, warpedImgGray, MORPH_OPEN, element); // Apply the specified morphology operation

    //Draw circles around the intersections for easy detection of black stones
    for( size_t i = 0; i < intersectionPoints.size(); i++ )
    {
         Point center(cvRound(intersectionPoints[i].x), cvRound(intersectionPoints[i].y));
         int radius = cvRound(stone_diameter/2);
         // draw the circle outline
         circle(warpedImgGray, center, radius, Scalar(255), 2, 8, 0 );
    }

    imshow("Image for detecting black stones", warpedImgGray);

    for(size_t i=0; i < intersectionPoints.size(); i++)
    {
        auto& intersection_point = intersectionPoints[i];

        int x = cvRound(intersectionPoints[i].x);
        int y = cvRound(intersectionPoints[i].y);
        int distance, diameter45, diameter125;

        /**
        * Let's check if this is a stone :). We'll read out the diameters at 45 and 125 if they
        * are similar -> it's a stone.
        */

        if (warpedImgGray.at<uchar>(y,x) < 20)
        {

            /**
            *    first we produce a help line to get the diameters at 45 and 125.
            *    therefore we use the intersectionpoints.
            */
            Point2i midpointLine;
            distance = getStoneDistanceAndMidpoint(warpedImgGray, x, y, LEFT, midpointLine);

            // Get the Diameter for 125 degree
            Point2i midpoint125;
            diameter125 = getStoneDistanceAndMidpoint(warpedImgGray, midpointLine.x, midpointLine.y, RIGHT, midpoint125);

            // Get the Diameter for 45 degree
            Point2i midpoint45;
            diameter45 = getStoneDistanceAndMidpoint(warpedImgGray, midpoint125.x, midpoint125.y, LEFT, midpoint45);

            //it's a stone if the diameters are similiar, not to small and not to big.

            int min_stone_size;
            int max_stone_size;

            //9x9
            if(board_size <= 9)
            {
                min_stone_size = 30;
                max_stone_size = 80;
            }
            //13x13
            else if (board_size <= 13)
            {
                min_stone_size = 20;
                max_stone_size = 60;
            }
            //19x19 ++
            else
            {
                min_stone_size = 15;
                max_stone_size = 50;
            }

            if(diameter125+5 >= diameter45 && diameter125-5 <= diameter45 && diameter45 >= min_stone_size && diameter125 >= min_stone_size  && diameter45 <= max_stone_size && diameter125 <= max_stone_size)
            {
                //cout << "Black Stone ("<< x << ", "<< y << ")" << endl;

                stones.Include(to_board_coords[intersection_point]);

                circle( paintedWarpedImg,
                Point(midpoint125.x, midpoint125.y),
                (diameter125/2),
                Scalar(0, 255, 0), 0, 8, 0);
            }
        }
    }
}

void detectAllStones(Mat& warpedImg, vector<Point2f> intersectionPoints, map<Point2f, SgPoint, lesserPoint2f> to_board_coords, SgPointSet& stones, float stone_diameter, Mat& paintedWarpedImg)
{
    using namespace cv;
    Mat img;

    cvtColor(warpedImg, img, CV_RGB2GRAY);
    Canny(img, img, 100, 150, 3);

    // After canny we get a binary image, where all detected edges are white.
    // Dilate iterates over ervery pixel, and sets the pixel to the maximum pixel value within a circle around that pixel.
    // This leaves the areas black where no edges were detected and thus could contain a stone.
    int dilate_value = static_cast<int>(stone_diameter*0.8+0.5f);
    Mat element_dilate = getStructuringElement(MORPH_ELLIPSE, Size(dilate_value, dilate_value));
    dilate(img, img, element_dilate);
    imshow("after dilating", img);

    // Only the intersection points (later accessed by img.at<uchar>(y,x)) are relevant.
    // Erode looks for the minimum pixel value (black) within a circle around every pixel.
    // Because black pixels represent possible stones, if there is any black pixel within
    // a stone radius around an intersection then we have found a stone.
    int erode_value = static_cast<int>(stone_diameter*0.6+0.5f);
    Mat element_erode = getStructuringElement(MORPH_ELLIPSE, Size(erode_value, erode_value));
    // todo(mihi314) could be optimized by not using erode and instead only doing the erode operation at intersection points
    erode(img, img, element_erode);

    imshow("Image for detecting all stones", img);

    for(size_t i=0; i < intersectionPoints.size(); i++)
    {
        auto& intersection_point = intersectionPoints[i];

        int x = cvRound(intersection_point.x);
        int y = cvRound(intersection_point.y);

        /**
        * Let's check if this is a stone :).
        */
        if (img.at<uchar>(y,x) < 50)
        {
            //cout << "Stone ("<< x << ", "<< y << ")" << endl;
            stones.Include(to_board_coords[intersection_point]);

            circle( paintedWarpedImg,
            Point(cvRound(intersectionPoints[i].x), cvRound(intersectionPoints[i].y)),
            cvRound(stone_diameter/2.0f),
            Scalar(238, 238, 176), 0, 8, 0);

        }
    }
}

// Map pixel coordinates (intersection points) to board coordinates
// Begins at the left of the lowermost line and gradually moves the lines from left to right upwards.
//
// Preconditions:
// - The number of intersection points must match board_size * board_size!
// - Each line (or column if you want) must have exactly the same number of intersection points as the board_size value
// - It is required that the intersection points on a specific line all have almost equal y-values!
//   Thats the decision criteria for selecting the points on a given line.
map<Point2f, SgPoint, lesserPoint2f> getBoardCoordMapFor(vector<Point2f> intersectionPoints, int board_size)
{
    const auto& num_lines = board_size;

    // Sort points by their descending y-values to begin at the lowermost point
    sort(begin(intersectionPoints), end(intersectionPoints), [](const Point2f& left, const Point2f& right) { return left.y > right.y; });

    // Walk through each line from left to right and map a board coordinate to each point,
    // iteratively looks at the next batch (num_lines points) of intersection points
    map<Point2f, SgPoint, lesserPoint2f> to_board_coordinates;
    int line_idx = 1;
    auto begin_iter = begin(intersectionPoints);
    for (auto i = 0; i < num_lines; ++i, begin_iter += num_lines) {
        // Get the next num_lines points (these will be the points on the i-th line from the bottom)
        decltype(intersectionPoints) points_on_this_line;
        copy( begin_iter,
                   begin_iter+num_lines,
                   back_inserter(points_on_this_line));

        // Sort by ascending x values of the points
        sort(begin(points_on_this_line), end(points_on_this_line), [](const Point2f& left, const Point2f& right) { return left.x < right.x; });

        // Add an entry for each point on this line to the map
        int column_idx = 1;
        for (const auto& pt : points_on_this_line) {
            to_board_coordinates[pt] = SgPointUtil::Pt(column_idx++, line_idx);
        }

        ++line_idx;
    }

    return to_board_coordinates;
}

bool getStones(Mat srcWarpedImg, vector<Point2f> intersectionPoints, GoSetup& setup, int& board_size,Mat& paintedWarpedImg)
{
    // Calc the minimum distance between the first intersection point to all others
    // The minimum distance is approximately the diameter of a stone
    vector<float> distances;
    const auto& ref_point_min = *begin(intersectionPoints);
    for (const auto& point : intersectionPoints) {
        if (point != ref_point_min)
            distances.push_back(norm(point - ref_point_min));
    }
    auto approx_stone_diameter = *min_element(begin(distances), end(distances));

    cerr << "Board size: " << board_size << endl;

    // get map from intersection points to board coordinates (SgPoint)
    auto to_board_coords = getBoardCoordMapFor(intersectionPoints, board_size);

    // detect the stones!
    SgPointSet all_stones;
    detectAllStones(srcWarpedImg, intersectionPoints, to_board_coords, all_stones, approx_stone_diameter, paintedWarpedImg);

    SgPointSet black_stones;
    detectBlackStones(srcWarpedImg, intersectionPoints, board_size, to_board_coords, approx_stone_diameter, black_stones, paintedWarpedImg);
    setup.m_stones[SG_BLACK] = black_stones;
    setup.m_stones[SG_WHITE] = all_stones - black_stones;

    return true;
}

}<|endoftext|>


<commit_before>// For conditions of distribution and use, see copyright notice in license.txt

#include "StableHeaders.h"
#include "DebugOperatorNew.h"
#include "EtherLoginNotifier.h"

#include "Data/RealXtendAvatar.h"
#include "Data/OpenSimAvatar.h"
#include "Data/OpenSimWorld.h"

#include "MemoryLeakCheck.h"

#include "ModuleManager.h"
#include "UiModule.h"
#include "Inworld/InworldSceneController.h"
#include "Inworld/ControlPanelManager.h"
#include "Inworld/ControlPanel/TeleportWidget.h"
#include "UiNotificationServices.h"

namespace Ether
{
    namespace Logic
    {
        EtherLoginNotifier::EtherLoginNotifier(QObject *parent, EtherSceneController *scene_controller, Foundation::Framework *framework)
            : QObject(parent),
              scene_controller_(scene_controller),
              framework_(framework)
        {
            boost::shared_ptr<UiServices::UiModule> ui_module =  framework_->GetModuleManager()->GetModule<UiServices::UiModule>(Foundation::Module::MT_UiServices).lock();
            if (ui_module)
                connect(ui_module->GetInworldSceneController()->GetControlPanelManager()->GetTeleportWidget(), SIGNAL(StartTeleport(QString)), SLOT(Teleport(QString)));
            teleporting = false;
        }

        void EtherLoginNotifier::ParseInfoFromData(QPair<Data::AvatarInfo*, Data::WorldInfo*> data_cards)
        {
            // Set last info card to default. Used for in world Teleporting
            last_info_map_.clear();

            QMap<QString, QString> info_map;
            switch (data_cards.second->worldType())
            {
                case WorldTypes::OpenSim:
                {
                    Data::OpenSimWorld *ow = dynamic_cast<Data::OpenSimWorld*>(data_cards.second);
                    info_map["WorldAddress"] = ow->loginUrl().toString();
                    info_map["StartLocation"] = ow->startLocation();
                    last_info_map_.insert("WorldAddress", ow->loginUrl().toString());
                    last_info_map_.insert("StartLocation", ow->startLocation());
                    break;
                }
            }

            switch (data_cards.first->avatarType())
            {
                case AvatarTypes::OpenSim:
                {
                    Data::OpenSimAvatar *oa = dynamic_cast<Data::OpenSimAvatar*>(data_cards.first);
                    info_map["Username"] = oa->userName();
                    info_map["Password"] = oa->password();
                    last_info_map_.insert("Username", oa->userName());
                    last_info_map_.insert("Password", oa->password());
                    last_info_map_.insert("AvatarType", "OpenSim");
                    emit StartOsLogin(info_map);
                    break;
                }
                case AvatarTypes::RealXtend:
                {
                    Data::RealXtendAvatar *ra = dynamic_cast<Data::RealXtendAvatar*>(data_cards.first);
                    info_map["Username"] = ra->account();
                    info_map["Password"] = ra->password();
                    info_map["AuthenticationAddress"] = ra->authUrl().toString();
                    last_info_map_.insert("Username", ra->account());
                    last_info_map_.insert("Password", ra->password());
                    last_info_map_.insert("AuthenticationAddress", ra->authUrl().toString());
                    last_info_map_.insert("AvatarType", "RealXtend");
                    emit StartRexLogin(info_map);
                    break;
                }
            }
        }

        void EtherLoginNotifier::EmitOpenSimLogin(QMap<QString, QString> info_map)
        {
            emit StartOsLogin(info_map);
        }

        void EtherLoginNotifier::EmitRealXtendLogin(QMap<QString, QString> info_map)
        {
            emit StartRexLogin(info_map);
        }

        void EtherLoginNotifier::EmitTaigaLogin(QWebFrame *web_frame)
        {
            emit StartTaigaLogin(web_frame);
        }

        void EtherLoginNotifier::EmitTaigaLogin(QString url)
        {
            emit StartTaigaLogin(url);
        }

        void EtherLoginNotifier::ExitApplication()
        {
            emit Quit();
        }

        void EtherLoginNotifier::Teleport(QString start_location)
        {
            if (!start_location.isEmpty())
            {
                last_info_map_.remove("StartLocation");
                last_info_map_.insert("StartLocation", start_location);

                QString avatarType = last_info_map_.value("AvatarType");
                if (avatarType.compare("OpenSim") == 0)
                    emit StartOsLogin(last_info_map_);
                else if (avatarType.compare("RealXtend") == 1)
                    emit StartRexLogin(last_info_map_);
                else if (avatarType.compare("RealXtend") == 0)
                {
                    UiServices::UiModule::LogError("Webauth avatars can't teleport yet.");
                    boost::shared_ptr<UiServices::UiModule> ui_module =  framework_->GetModuleManager()->GetModule<UiServices::UiModule>(Foundation::Module::MT_UiServices).lock();
                    if (ui_module)
                        ui_module->GetNotificationManager()->ShowNotification(new UiServices::MessageNotification("Webauth avatars cannot teleport yet, sorry."));
                }
                else
                {
                    UiServices::UiModule::LogInfo("Teleport failed. Unknown avatar type: "+avatarType.toStdString());
                }

            }

        }

        void EtherLoginNotifier::ScriptTeleportAnswer(QString answer, QString region_name)
        {
            if (answer.isEmpty())
                return;

            if (answer.compare("Yes") == 0)
            {
                QTimer::singleShot(1000, this, SLOT(ScriptTeleport()));
                region_name_ = region_name;
            }
            else if (answer.compare("No") == 0)
            {
                teleporting = false;
            }
        }

        void EtherLoginNotifier::ScriptTeleport()
        {
            teleporting = false;
            Teleport(region_name_);
        }
    }
}
<commit_msg>Minor fix to teleport logic.<commit_after>// For conditions of distribution and use, see copyright notice in license.txt

#include "StableHeaders.h"
#include "DebugOperatorNew.h"
#include "EtherLoginNotifier.h"

#include "Data/RealXtendAvatar.h"
#include "Data/OpenSimAvatar.h"
#include "Data/OpenSimWorld.h"

#include "MemoryLeakCheck.h"

#include "ModuleManager.h"
#include "UiModule.h"
#include "Inworld/InworldSceneController.h"
#include "Inworld/ControlPanelManager.h"
#include "Inworld/ControlPanel/TeleportWidget.h"
#include "UiNotificationServices.h"

namespace Ether
{
    namespace Logic
    {
        EtherLoginNotifier::EtherLoginNotifier(QObject *parent, EtherSceneController *scene_controller, Foundation::Framework *framework)
            : QObject(parent),
              scene_controller_(scene_controller),
              framework_(framework)
        {
            boost::shared_ptr<UiServices::UiModule> ui_module =  framework_->GetModuleManager()->GetModule<UiServices::UiModule>(Foundation::Module::MT_UiServices).lock();
            if (ui_module)
                connect(ui_module->GetInworldSceneController()->GetControlPanelManager()->GetTeleportWidget(), SIGNAL(StartTeleport(QString)), SLOT(Teleport(QString)));
            teleporting = false;
        }

        void EtherLoginNotifier::ParseInfoFromData(QPair<Data::AvatarInfo*, Data::WorldInfo*> data_cards)
        {
            // Set last info card to default. Used for in world Teleporting
            last_info_map_.clear();

            QMap<QString, QString> info_map;
            switch (data_cards.second->worldType())
            {
                case WorldTypes::OpenSim:
                {
                    Data::OpenSimWorld *ow = dynamic_cast<Data::OpenSimWorld*>(data_cards.second);
                    info_map["WorldAddress"] = ow->loginUrl().toString();
                    info_map["StartLocation"] = ow->startLocation();
                    last_info_map_.insert("WorldAddress", ow->loginUrl().toString());
                    last_info_map_.insert("StartLocation", ow->startLocation());
                    break;
                }
            }

            switch (data_cards.first->avatarType())
            {
                case AvatarTypes::OpenSim:
                {
                    Data::OpenSimAvatar *oa = dynamic_cast<Data::OpenSimAvatar*>(data_cards.first);
                    info_map["Username"] = oa->userName();
                    info_map["Password"] = oa->password();
                    last_info_map_.insert("Username", oa->userName());
                    last_info_map_.insert("Password", oa->password());
                    last_info_map_.insert("AvatarType", "OpenSim");
                    emit StartOsLogin(info_map);
                    break;
                }
                case AvatarTypes::RealXtend:
                {
                    Data::RealXtendAvatar *ra = dynamic_cast<Data::RealXtendAvatar*>(data_cards.first);
                    info_map["Username"] = ra->account();
                    info_map["Password"] = ra->password();
                    info_map["AuthenticationAddress"] = ra->authUrl().toString();
                    last_info_map_.insert("Username", ra->account());
                    last_info_map_.insert("Password", ra->password());
                    last_info_map_.insert("AuthenticationAddress", ra->authUrl().toString());
                    last_info_map_.insert("AvatarType", "RealXtend");
                    emit StartRexLogin(info_map);
                    break;
                }
            }
        }

        void EtherLoginNotifier::EmitOpenSimLogin(QMap<QString, QString> info_map)
        {
            emit StartOsLogin(info_map);
        }

        void EtherLoginNotifier::EmitRealXtendLogin(QMap<QString, QString> info_map)
        {
            emit StartRexLogin(info_map);
        }

        void EtherLoginNotifier::EmitTaigaLogin(QWebFrame *web_frame)
        {
            emit StartTaigaLogin(web_frame);
        }

        void EtherLoginNotifier::EmitTaigaLogin(QString url)
        {
            emit StartTaigaLogin(url);
        }

        void EtherLoginNotifier::ExitApplication()
        {
            emit Quit();
        }

        void EtherLoginNotifier::Teleport(QString start_location)
        {
            if (!start_location.isEmpty())
            {
                last_info_map_.remove("StartLocation");
                last_info_map_.insert("StartLocation", start_location);

                QString avatarType = last_info_map_.value("AvatarType");
                if (avatarType.compare("OpenSim") == 0)
                    emit StartOsLogin(last_info_map_);
                else if (avatarType.compare("RealXtend") == 0)
                    emit StartRexLogin(last_info_map_);
                else
                {
                    UiServices::UiModule::LogError("Webauth avatars can't teleport yet.");
                    boost::shared_ptr<UiServices::UiModule> ui_module =  framework_->GetModuleManager()->GetModule<UiServices::UiModule>(Foundation::Module::MT_UiServices).lock();
                    if (ui_module)
                        ui_module->GetNotificationManager()->ShowNotification(new UiServices::MessageNotification("Webauth avatars cannot teleport yet, sorry."));
                }
            }

        }

        void EtherLoginNotifier::ScriptTeleportAnswer(QString answer, QString region_name)
        {
            if (answer.isEmpty())
                return;

            if (answer.compare("Yes") == 0)
            {
                QTimer::singleShot(1000, this, SLOT(ScriptTeleport()));
                region_name_ = region_name;
            }
            else if (answer.compare("No") == 0)
            {
                teleporting = false;
            }
        }

        void EtherLoginNotifier::ScriptTeleport()
        {
            teleporting = false;
            Teleport(region_name_);
        }
    }
}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkSpherePuzzle.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkSpherePuzzle.h"

#include "vtkAppendPolyData.h"
#include "vtkGarbageCollector.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkLinearExtrusionFilter.h"
#include "vtkMath.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkPolyData.h"
#include "vtkSphereSource.h"
#include "vtkTransform.h"
#include "vtkTransformFilter.h"

#include <math.h>

vtkCxxRevisionMacro(vtkSpherePuzzle, "1.17");
vtkStandardNewMacro(vtkSpherePuzzle);

//----------------------------------------------------------------------------
// Construct a new puzzle.
vtkSpherePuzzle::vtkSpherePuzzle()
{
  this->Transform = vtkTransform::New();
  this->Reset();
  this->Active = 0;

  this->SetNumberOfInputPorts(0);
}

//----------------------------------------------------------------------------
// Construct a new puzzle.
vtkSpherePuzzle::~vtkSpherePuzzle()
{
  this->Transform->Delete();
  this->Transform = NULL;
}

//----------------------------------------------------------------------------
void vtkSpherePuzzle::Reset()
{
  int idx;

  this->Modified();
  for (idx = 0; idx < 32; ++idx)
    {
    this->State[idx] = idx;
    this->PieceMask[idx] = 0;
    }
  this->Transform->Identity();
  for (idx = 0; idx < 4; ++idx)
    {
    this->Colors[0 + idx*8*3] = 255;
    this->Colors[1 + idx*8*3] = 0;
    this->Colors[2 + idx*8*3] = 0;

    this->Colors[3 + idx*8*3] = 255;
    this->Colors[4 + idx*8*3] = 175;
    this->Colors[5 + idx*8*3] = 0;

    this->Colors[6 + idx*8*3] = 255;
    this->Colors[7 + idx*8*3] = 255;
    this->Colors[8 + idx*8*3] = 0;

    this->Colors[9 + idx*8*3] = 0;
    this->Colors[10 + idx*8*3] = 255;
    this->Colors[11 + idx*8*3] = 0;

    this->Colors[12 + idx*8*3] = 0;
    this->Colors[13 + idx*8*3] = 255;
    this->Colors[14 + idx*8*3] = 255;

    this->Colors[15 + idx*8*3] = 0;
    this->Colors[16 + idx*8*3] = 0;
    this->Colors[17 + idx*8*3] = 255;

    this->Colors[18 + idx*8*3] = 175;
    this->Colors[19 + idx*8*3] = 0;
    this->Colors[20 + idx*8*3] = 255;

    this->Colors[21 + idx*8*3] = 255;
    this->Colors[22 + idx*8*3] = 50;
    this->Colors[23 + idx*8*3] = 150;
    }
}

//----------------------------------------------------------------------------
int vtkSpherePuzzle::RequestData(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **vtkNotUsed(inputVector),
  vtkInformationVector *outputVector)
{
  // get the info object
  vtkInformation *outInfo = outputVector->GetInformationObject(0);

  // get the ouptut
  vtkPolyData *output = vtkPolyData::SafeDownCast(
    outInfo->Get(vtkDataObject::DATA_OBJECT()));

  // We are about to create/destroy alot of objects.  Defer garbage
  // collection until we are done.
  vtkGarbageCollector::DeferredCollectionPush();

  int i, j, k, num;
  int color;
  vtkAppendPolyData *append = vtkAppendPolyData::New();
  vtkSphereSource *sphere = vtkSphereSource::New();
  vtkTransformFilter *tf = vtkTransformFilter::New();
  vtkUnsignedCharArray *scalars = vtkUnsignedCharArray::New();
  vtkPolyData *tmp;
  int count = 0;
  unsigned char r, g, b;

  scalars->SetNumberOfComponents(3);

  sphere->SetPhiResolution(4);
  sphere->SetThetaResolution(4);

  tf->SetTransform(this->Transform);
  tf->SetInput(sphere->GetOutput());

  for (j = 0; j < 4; ++j)
    {
    for (i = 0; i < 8; ++i)
      {
      color = this->State[count] * 3;
      sphere->SetStartTheta((360.0 * (double)(i) / 8.0));
      sphere->SetEndTheta((360.0 * (double)(i+1) / 8.0));
      sphere->SetStartPhi((180.0 * (double)(j) / 4.0));
      sphere->SetEndPhi((180.0 * (double)(j+1) / 4.0));
      tmp = vtkPolyData::New();
      if (this->PieceMask[count])
        { // Spheres original output is transforms input. Put it back.
        tf->Update();
        tmp->ShallowCopy(tf->GetOutput());
        }
      else
        { // Piece not involved in partial move. Just use the sphere.
        sphere->Update();
        tmp->ShallowCopy(sphere->GetOutput());
        }
      // Now create the colors for the faces.
      num = tmp->GetNumberOfPoints();
      for (k = 0; k < num; ++k)
        {
        r = this->Colors[color];
        g = this->Colors[color+1];
        b = this->Colors[color+2];
        // Lighten the active pieces
        if (this->Active && this->PieceMask[count])
          {
          r = r + (unsigned char)((255 - r) * 0.4);
          g = g + (unsigned char)((255 - g) * 0.4);
          b = b + (unsigned char)((255 - b) * 0.4);
          }
        scalars->InsertNextValue(r);
        scalars->InsertNextValue(g);
        scalars->InsertNextValue(b);
        }

      // append all the pieces.
      append->AddInput(tmp);
      tmp->Delete();
      ++count;
      }
    }

  append->Update();

  // Move the data to the output.
  tmp = output;
  tmp->CopyStructure(append->GetOutput());
  tmp->GetPointData()->PassData(append->GetOutput()->GetPointData());
  tmp->GetPointData()->SetScalars(scalars);

  sphere->Delete();
  scalars->Delete();
  append->Delete();
  tf->Delete();

  // We are done creating/destroying objects.
  vtkGarbageCollector::DeferredCollectionPop();

  return 1;
}

//----------------------------------------------------------------------------
void vtkSpherePuzzle::MarkHorizontal(int section)
{
  int i;

  for (i = 0; i < 32; ++i)
    {
    this->PieceMask[i] = 0;
    }
  // Find the start of the section.
  section = section * 8;
  for (i = 0; i < 8; ++i)
    {
    this->PieceMask[i+section] = 1;
    }
}

//----------------------------------------------------------------------------
void vtkSpherePuzzle::MarkVertical(int section)
{
  int i, j, offset;

  for (i = 0; i < 32; ++i)
    {
    this->PieceMask[i] = 1;
    }
  for (i = 0; i < 4; ++i)
    {
    offset = (section + i) % 8;
    for (j = 0; j < 4; ++j)
      {
      this->PieceMask[offset+(j*8)] = 0;
      }
    }
}

//----------------------------------------------------------------------------
void vtkSpherePuzzle::MoveHorizontal(int slab, int percentage, int rightFlag)
{
  int offset;
  int tmp;
  int i;

  this->Modified();

  // Clear out previous partial moves.
  this->Transform->Identity();
  this->MarkHorizontal(slab);

  // Move zero does nothing.
  if (percentage <= 0)
    {
    return;
    }

  // Offset is used to determine which pieces are involved.
  offset = slab * 8;

  // Move 100 percent changes state.
  if (percentage >= 100)
    { // Just do the state change.
    if (rightFlag)
      {
      tmp = this->State[offset+7];
      for (i = 7; i > 0; --i)
        {
        this->State[i+offset] = this->State[i-1+offset];
        }
      this->State[offset] = tmp;
      }
    else
      {
      tmp = this->State[offset];
      for (i = 0; i < 7; ++i)
        {
        this->State[i+offset] = this->State[i+1+offset];
        }
      this->State[offset+7] = tmp;
      }
    return;
    }

  // Partial move.
  // This does not change the state.  It is ust for animating
  // the move.
  // Setup the pieces that are involved in the move.
  if ( ! rightFlag)
    {
    percentage = -percentage;
    }
  this->Transform->RotateZ(((double)(percentage) / 100.0)
                           * (360.0 / 8.0) );
}

//----------------------------------------------------------------------------
void vtkSpherePuzzle::MoveVertical(int half, int percentage, int rightFlag)
{
  int tmp;
  int off0, off1, off2, off3;
  double theta;

  this->Modified();

  // Clear out previous partial moves.
  this->Transform->Identity();
  this->MarkVertical(half);

  // Move zero does nothing.
  if (percentage <= 0)
    {
    return;
    }

  off0 = (4+half) % 8;
  off1 = (5+half) % 8;
  off2 = (6+half) % 8;
  off3 = (7+half) % 8;

  // Move 100 percent changes state.
  if (percentage >= 100)
    { // Just do the state change.
    tmp = this->State[off0];
    this->State[off0] = this->State[24+off3];
    this->State[24+off3] = tmp;

    tmp = this->State[off1];
    this->State[off1] = this->State[24+off2];
    this->State[24+off2] = tmp;

    tmp = this->State[off2];
    this->State[off2] = this->State[24+off1];
    this->State[24+off1] = tmp;

    tmp = this->State[off3];
    this->State[off3] = this->State[24+off0];
    this->State[24+off0] = tmp;

    tmp = this->State[8+off0];
    this->State[8+off0] = this->State[16+off3];
    this->State[16+off3] = tmp;

    tmp = this->State[8+off1];
    this->State[8+off1] = this->State[16+off2];
    this->State[16+off2] = tmp;

    tmp = this->State[8+off2];
    this->State[8+off2] = this->State[16+off1];
    this->State[16+off1] = tmp;

    tmp = this->State[8+off3];
    this->State[8+off3] = this->State[16+off0];
    this->State[16+off0] = tmp;
    return;
    }

  // Partial move.
  // This does not change the state.  It is use for animating the move.
  if (rightFlag)
    {
    percentage = -percentage;
    }
  theta = (double)(half) * vtkMath::Pi() / 4.0;
  this->Transform->RotateWXYZ(((double)(percentage)/100.0)*(360.0/2.0),
                              sin(theta), -cos(theta), 0.0);

}

//----------------------------------------------------------------------------
int vtkSpherePuzzle::SetPoint(double x, double y, double z)
{
  double pt[3];
  double theta, phi;
  int xi, yi;
  double xp, yp;
  double xn, yn;

  this->Modified();

  if (x < 0.2 && x > -0.2 && y < 0.2 && y > -0.2 && z < 0.2 && z > -0.2)
    {
    this->Active = 0;
    return 0;
    }

  // normalize
  pt[0] = x;
  pt[1] = y;
  pt[2] = z;
  vtkMath::Normalize(pt);

  // Convert this into phi and theta.
  theta = 180.0 - atan2(pt[0], pt[1]) * 180 / vtkMath::Pi();
  phi = 90.0 - asin(pt[2]) * 180 / vtkMath::Pi();

  // Compute the piece the point is in.
  xi = (int)(theta * 8.0 / 360.0);
  yi = (int)(phi * 8 / 360.0);
  xn = (theta/(360.0/8.0)) - (double)(xi);
  yn = (phi/(360.0/8.0)) - (double)(yi);

  //vtkErrorMacro("point: " << x << ", " << y << ", " << z);
  //vtkErrorMacro("theta: " << theta << ",  phi: " << phi);
  //vtkErrorMacro("theta: " << xi << ", " << xn << ",  phi: " << yi << ", " << y);

  xp = 1.0 - xn;
  yp = 1.0 - yn;
  if (xn > 0.2 && xp > 0.2 && yn > 0.2 && yp > 0.2)
    { // Do nothing in the center of the face.
    this->Active = 0;
    return 0;
    }
  this->Active = 1;
  if (xn < xp && xn < yp && xn < yn)
    {
    this->VerticalFlag = 1;
    this->RightFlag = (yn < yp);
    this->Section = xi+2;
    this->MarkVertical(this->Section);
    return this->Section + this->VerticalFlag * 10 + this->RightFlag * 100;
    }
  if (xp < xn && xp < yp && xp < yn)
    {
    this->VerticalFlag = 1;
    this->RightFlag = (yp < yn);
    this->Section = xi+7;
    this->MarkVertical(this->Section);
    return this->Section + this->VerticalFlag * 10 + this->RightFlag * 100;
    }
  // The remaining options move a horizontal slab.
  this->VerticalFlag = 0;
  this->RightFlag = (xn > xp);
  this->Section = yi;
  this->MarkHorizontal(this->Section);
  return this->Section + this->VerticalFlag * 10 + this->RightFlag * 100;
}

//----------------------------------------------------------------------------
void vtkSpherePuzzle::MovePoint(int percentage)
{
  if ( ! this->Active)
    {
    return;
    }
  this->Modified();

  if (this->VerticalFlag)
    {
    this->MoveVertical(this->Section, percentage, this->RightFlag);
    }
  else
    {
    this->MoveHorizontal(this->Section, percentage, this->RightFlag);
    }
}

//----------------------------------------------------------------------------
void vtkSpherePuzzle::PrintSelf(ostream& os, vtkIndent indent)
{
  int idx;
  this->Superclass::PrintSelf(os,indent);

  os << indent << "State: " << this->State[0];
  for (idx = 1; idx < 16; ++idx)
    {
    os << ", " << this->State[idx];
    }
  os << endl;
}
<commit_msg>ENH: now uses fast delete<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkSpherePuzzle.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkSpherePuzzle.h"

#include "vtkAppendPolyData.h"
#include "vtkGarbageCollector.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkLinearExtrusionFilter.h"
#include "vtkMath.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkPolyData.h"
#include "vtkSphereSource.h"
#include "vtkTransform.h"
#include "vtkTransformFilter.h"

#include <math.h>

vtkCxxRevisionMacro(vtkSpherePuzzle, "1.18");
vtkStandardNewMacro(vtkSpherePuzzle);

//----------------------------------------------------------------------------
// Construct a new puzzle.
vtkSpherePuzzle::vtkSpherePuzzle()
{
  this->Transform = vtkTransform::New();
  this->Reset();
  this->Active = 0;

  this->SetNumberOfInputPorts(0);
}

//----------------------------------------------------------------------------
// Construct a new puzzle.
vtkSpherePuzzle::~vtkSpherePuzzle()
{
  this->Transform->Delete();
  this->Transform = NULL;
}

//----------------------------------------------------------------------------
void vtkSpherePuzzle::Reset()
{
  int idx;

  this->Modified();
  for (idx = 0; idx < 32; ++idx)
    {
    this->State[idx] = idx;
    this->PieceMask[idx] = 0;
    }
  this->Transform->Identity();
  for (idx = 0; idx < 4; ++idx)
    {
    this->Colors[0 + idx*8*3] = 255;
    this->Colors[1 + idx*8*3] = 0;
    this->Colors[2 + idx*8*3] = 0;

    this->Colors[3 + idx*8*3] = 255;
    this->Colors[4 + idx*8*3] = 175;
    this->Colors[5 + idx*8*3] = 0;

    this->Colors[6 + idx*8*3] = 255;
    this->Colors[7 + idx*8*3] = 255;
    this->Colors[8 + idx*8*3] = 0;

    this->Colors[9 + idx*8*3] = 0;
    this->Colors[10 + idx*8*3] = 255;
    this->Colors[11 + idx*8*3] = 0;

    this->Colors[12 + idx*8*3] = 0;
    this->Colors[13 + idx*8*3] = 255;
    this->Colors[14 + idx*8*3] = 255;

    this->Colors[15 + idx*8*3] = 0;
    this->Colors[16 + idx*8*3] = 0;
    this->Colors[17 + idx*8*3] = 255;

    this->Colors[18 + idx*8*3] = 175;
    this->Colors[19 + idx*8*3] = 0;
    this->Colors[20 + idx*8*3] = 255;

    this->Colors[21 + idx*8*3] = 255;
    this->Colors[22 + idx*8*3] = 50;
    this->Colors[23 + idx*8*3] = 150;
    }
}

//----------------------------------------------------------------------------
int vtkSpherePuzzle::RequestData(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **vtkNotUsed(inputVector),
  vtkInformationVector *outputVector)
{
  // get the info object
  vtkInformation *outInfo = outputVector->GetInformationObject(0);

  // get the ouptut
  vtkPolyData *output = vtkPolyData::SafeDownCast(
    outInfo->Get(vtkDataObject::DATA_OBJECT()));

  // We are about to create/destroy alot of objects.  Defer garbage
  // collection until we are done.
  vtkGarbageCollector::DeferredCollectionPush();

  int i, j, k, num;
  int color;
  vtkAppendPolyData *append = vtkAppendPolyData::New();
  vtkSphereSource *sphere = vtkSphereSource::New();
  vtkTransformFilter *tf = vtkTransformFilter::New();
  vtkUnsignedCharArray *scalars = vtkUnsignedCharArray::New();
  vtkPolyData *tmp;
  int count = 0;
  unsigned char r, g, b;

  scalars->SetNumberOfComponents(3);

  sphere->SetPhiResolution(4);
  sphere->SetThetaResolution(4);

  tf->SetTransform(this->Transform);
  tf->SetInput(sphere->GetOutput());

  for (j = 0; j < 4; ++j)
    {
    for (i = 0; i < 8; ++i)
      {
      color = this->State[count] * 3;
      sphere->SetStartTheta((360.0 * (double)(i) / 8.0));
      sphere->SetEndTheta((360.0 * (double)(i+1) / 8.0));
      sphere->SetStartPhi((180.0 * (double)(j) / 4.0));
      sphere->SetEndPhi((180.0 * (double)(j+1) / 4.0));
      tmp = vtkPolyData::New();
      if (this->PieceMask[count])
        { // Spheres original output is transforms input. Put it back.
        tf->Update();
        tmp->ShallowCopy(tf->GetOutput());
        }
      else
        { // Piece not involved in partial move. Just use the sphere.
        sphere->Update();
        tmp->ShallowCopy(sphere->GetOutput());
        }
      // Now create the colors for the faces.
      num = tmp->GetNumberOfPoints();
      for (k = 0; k < num; ++k)
        {
        r = this->Colors[color];
        g = this->Colors[color+1];
        b = this->Colors[color+2];
        // Lighten the active pieces
        if (this->Active && this->PieceMask[count])
          {
          r = r + (unsigned char)((255 - r) * 0.4);
          g = g + (unsigned char)((255 - g) * 0.4);
          b = b + (unsigned char)((255 - b) * 0.4);
          }
        scalars->InsertNextValue(r);
        scalars->InsertNextValue(g);
        scalars->InsertNextValue(b);
        }

      // append all the pieces.
      append->AddInput(tmp);
      tmp->FastDelete();
      ++count;
      }
    }

  append->Update();

  // Move the data to the output.
  tmp = output;
  tmp->CopyStructure(append->GetOutput());
  tmp->GetPointData()->PassData(append->GetOutput()->GetPointData());
  tmp->GetPointData()->SetScalars(scalars);

  sphere->Delete();
  scalars->Delete();
  append->Delete();
  tf->Delete();

  // We are done creating/destroying objects.
  vtkGarbageCollector::DeferredCollectionPop();

  return 1;
}

//----------------------------------------------------------------------------
void vtkSpherePuzzle::MarkHorizontal(int section)
{
  int i;

  for (i = 0; i < 32; ++i)
    {
    this->PieceMask[i] = 0;
    }
  // Find the start of the section.
  section = section * 8;
  for (i = 0; i < 8; ++i)
    {
    this->PieceMask[i+section] = 1;
    }
}

//----------------------------------------------------------------------------
void vtkSpherePuzzle::MarkVertical(int section)
{
  int i, j, offset;

  for (i = 0; i < 32; ++i)
    {
    this->PieceMask[i] = 1;
    }
  for (i = 0; i < 4; ++i)
    {
    offset = (section + i) % 8;
    for (j = 0; j < 4; ++j)
      {
      this->PieceMask[offset+(j*8)] = 0;
      }
    }
}

//----------------------------------------------------------------------------
void vtkSpherePuzzle::MoveHorizontal(int slab, int percentage, int rightFlag)
{
  int offset;
  int tmp;
  int i;

  this->Modified();

  // Clear out previous partial moves.
  this->Transform->Identity();
  this->MarkHorizontal(slab);

  // Move zero does nothing.
  if (percentage <= 0)
    {
    return;
    }

  // Offset is used to determine which pieces are involved.
  offset = slab * 8;

  // Move 100 percent changes state.
  if (percentage >= 100)
    { // Just do the state change.
    if (rightFlag)
      {
      tmp = this->State[offset+7];
      for (i = 7; i > 0; --i)
        {
        this->State[i+offset] = this->State[i-1+offset];
        }
      this->State[offset] = tmp;
      }
    else
      {
      tmp = this->State[offset];
      for (i = 0; i < 7; ++i)
        {
        this->State[i+offset] = this->State[i+1+offset];
        }
      this->State[offset+7] = tmp;
      }
    return;
    }

  // Partial move.
  // This does not change the state.  It is ust for animating
  // the move.
  // Setup the pieces that are involved in the move.
  if ( ! rightFlag)
    {
    percentage = -percentage;
    }
  this->Transform->RotateZ(((double)(percentage) / 100.0)
                           * (360.0 / 8.0) );
}

//----------------------------------------------------------------------------
void vtkSpherePuzzle::MoveVertical(int half, int percentage, int rightFlag)
{
  int tmp;
  int off0, off1, off2, off3;
  double theta;

  this->Modified();

  // Clear out previous partial moves.
  this->Transform->Identity();
  this->MarkVertical(half);

  // Move zero does nothing.
  if (percentage <= 0)
    {
    return;
    }

  off0 = (4+half) % 8;
  off1 = (5+half) % 8;
  off2 = (6+half) % 8;
  off3 = (7+half) % 8;

  // Move 100 percent changes state.
  if (percentage >= 100)
    { // Just do the state change.
    tmp = this->State[off0];
    this->State[off0] = this->State[24+off3];
    this->State[24+off3] = tmp;

    tmp = this->State[off1];
    this->State[off1] = this->State[24+off2];
    this->State[24+off2] = tmp;

    tmp = this->State[off2];
    this->State[off2] = this->State[24+off1];
    this->State[24+off1] = tmp;

    tmp = this->State[off3];
    this->State[off3] = this->State[24+off0];
    this->State[24+off0] = tmp;

    tmp = this->State[8+off0];
    this->State[8+off0] = this->State[16+off3];
    this->State[16+off3] = tmp;

    tmp = this->State[8+off1];
    this->State[8+off1] = this->State[16+off2];
    this->State[16+off2] = tmp;

    tmp = this->State[8+off2];
    this->State[8+off2] = this->State[16+off1];
    this->State[16+off1] = tmp;

    tmp = this->State[8+off3];
    this->State[8+off3] = this->State[16+off0];
    this->State[16+off0] = tmp;
    return;
    }

  // Partial move.
  // This does not change the state.  It is use for animating the move.
  if (rightFlag)
    {
    percentage = -percentage;
    }
  theta = (double)(half) * vtkMath::Pi() / 4.0;
  this->Transform->RotateWXYZ(((double)(percentage)/100.0)*(360.0/2.0),
                              sin(theta), -cos(theta), 0.0);

}

//----------------------------------------------------------------------------
int vtkSpherePuzzle::SetPoint(double x, double y, double z)
{
  double pt[3];
  double theta, phi;
  int xi, yi;
  double xp, yp;
  double xn, yn;

  this->Modified();

  if (x < 0.2 && x > -0.2 && y < 0.2 && y > -0.2 && z < 0.2 && z > -0.2)
    {
    this->Active = 0;
    return 0;
    }

  // normalize
  pt[0] = x;
  pt[1] = y;
  pt[2] = z;
  vtkMath::Normalize(pt);

  // Convert this into phi and theta.
  theta = 180.0 - atan2(pt[0], pt[1]) * 180 / vtkMath::Pi();
  phi = 90.0 - asin(pt[2]) * 180 / vtkMath::Pi();

  // Compute the piece the point is in.
  xi = (int)(theta * 8.0 / 360.0);
  yi = (int)(phi * 8 / 360.0);
  xn = (theta/(360.0/8.0)) - (double)(xi);
  yn = (phi/(360.0/8.0)) - (double)(yi);

  //vtkErrorMacro("point: " << x << ", " << y << ", " << z);
  //vtkErrorMacro("theta: " << theta << ",  phi: " << phi);
  //vtkErrorMacro("theta: " << xi << ", " << xn << ",  phi: " << yi << ", " << y);

  xp = 1.0 - xn;
  yp = 1.0 - yn;
  if (xn > 0.2 && xp > 0.2 && yn > 0.2 && yp > 0.2)
    { // Do nothing in the center of the face.
    this->Active = 0;
    return 0;
    }
  this->Active = 1;
  if (xn < xp && xn < yp && xn < yn)
    {
    this->VerticalFlag = 1;
    this->RightFlag = (yn < yp);
    this->Section = xi+2;
    this->MarkVertical(this->Section);
    return this->Section + this->VerticalFlag * 10 + this->RightFlag * 100;
    }
  if (xp < xn && xp < yp && xp < yn)
    {
    this->VerticalFlag = 1;
    this->RightFlag = (yp < yn);
    this->Section = xi+7;
    this->MarkVertical(this->Section);
    return this->Section + this->VerticalFlag * 10 + this->RightFlag * 100;
    }
  // The remaining options move a horizontal slab.
  this->VerticalFlag = 0;
  this->RightFlag = (xn > xp);
  this->Section = yi;
  this->MarkHorizontal(this->Section);
  return this->Section + this->VerticalFlag * 10 + this->RightFlag * 100;
}

//----------------------------------------------------------------------------
void vtkSpherePuzzle::MovePoint(int percentage)
{
  if ( ! this->Active)
    {
    return;
    }
  this->Modified();

  if (this->VerticalFlag)
    {
    this->MoveVertical(this->Section, percentage, this->RightFlag);
    }
  else
    {
    this->MoveHorizontal(this->Section, percentage, this->RightFlag);
    }
}

//----------------------------------------------------------------------------
void vtkSpherePuzzle::PrintSelf(ostream& os, vtkIndent indent)
{
  int idx;
  this->Superclass::PrintSelf(os,indent);

  os << indent << "State: " << this->State[0];
  for (idx = 1; idx < 16; ++idx)
    {
    os << ", " << this->State[idx];
    }
  os << endl;
}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkSplineFilter.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkSplineFilter.h"

#include "vtkCardinalSpline.h"
#include "vtkCell.h"
#include "vtkCellArray.h"
#include "vtkCellData.h"
#include "vtkFloatArray.h"
#include "vtkMath.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkPolyData.h"

vtkCxxRevisionMacro(vtkSplineFilter, "1.17");
vtkStandardNewMacro(vtkSplineFilter);
vtkCxxSetObjectMacro(vtkSplineFilter,Spline,vtkSpline);

vtkSplineFilter::vtkSplineFilter()
{
  this->Subdivide = VTK_SUBDIVIDE_SPECIFIED;
  this->MaximumNumberOfSubdivisions = VTK_LARGE_INTEGER;
  this->NumberOfSubdivisions = 100;
  this->Length = 0.1;
  this->GenerateTCoords = VTK_TCOORDS_FROM_NORMALIZED_LENGTH;
  this->TextureLength = 1.0;

  this->Spline = vtkCardinalSpline::New();
  this->TCoordMap = vtkFloatArray::New();
}

vtkSplineFilter::~vtkSplineFilter()
{
  if (this->Spline)
    {
    this->Spline->Delete();
    this->Spline = 0;
    }

  if (this->TCoordMap)
    {
    this->TCoordMap->Delete();
    this->TCoordMap = 0;
    }
}

int vtkSplineFilter::RequestData(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **inputVector,
  vtkInformationVector *outputVector)
{
  // get the info objects
  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
  vtkInformation *outInfo = outputVector->GetInformationObject(0);

  // get the input and ouptut
  vtkPolyData *input = vtkPolyData::SafeDownCast(
    inInfo->Get(vtkDataObject::DATA_OBJECT()));
  vtkPolyData *output = vtkPolyData::SafeDownCast(
    outInfo->Get(vtkDataObject::DATA_OBJECT()));

  vtkPointData *pd=input->GetPointData();
  vtkPointData *outPD=output->GetPointData();
  vtkCellData *cd=input->GetCellData();
  vtkCellData *outCD=output->GetCellData();
  vtkCellArray *inLines;

  vtkPoints *inPts;
  vtkIdType numLines;
  vtkCellArray *newLines;
  vtkIdType numNewPts, numNewCells;
  vtkPoints *newPts;
  vtkIdType npts=0, *pts=NULL;
  vtkIdType offset=0;
  vtkFloatArray *newTCoords=NULL;
  int abort=0;
  vtkIdType inCellId, numGenPts;
  int genTCoords = VTK_TCOORDS_OFF;

  // Check input and initialize
  //
  vtkDebugMacro(<<"Splining polylines");

  if ( !(inPts=input->GetPoints()) || inPts->GetNumberOfPoints() < 1 ||
      !(inLines = input->GetLines()) ||
       (numLines = inLines->GetNumberOfCells()) < 1 )
    {
    vtkWarningMacro(<< " No input data!");
    return 1;
    }

  if ( this->Spline == NULL )
    {
    vtkWarningMacro(<< "Need to specify a spline!");
    return 1;
    }

  // Create the geometry and topology
  numNewPts = this->NumberOfSubdivisions * numLines;
  newPts = vtkPoints::New();
  newPts->Allocate(numNewPts);
  newLines = vtkCellArray::New();
  newLines->Allocate(newLines->EstimateSize(1,numNewPts));

  // Point data
  if ( (this->GenerateTCoords == VTK_TCOORDS_FROM_SCALARS &&
        pd->GetScalars() != NULL) ||
       (this->GenerateTCoords == VTK_TCOORDS_FROM_LENGTH ||
        this->GenerateTCoords == VTK_TCOORDS_FROM_NORMALIZED_LENGTH) )
    {
    genTCoords = this->GenerateTCoords;
    newTCoords = vtkFloatArray::New();
    newTCoords->SetNumberOfComponents(2);
    newTCoords->Allocate(numNewPts);
    outPD->CopyTCoordsOff();
    }
  outPD->InterpolateAllocate(pd,numNewPts);
  this->TCoordMap->Allocate(VTK_CELL_SIZE);

  // Copy cell data
  numNewCells = numLines;
  outCD->CopyNormalsOff();
  outCD->CopyAllocate(cd,numNewCells);

  // Set up the splines
  this->XSpline = this->Spline->NewInstance();
  this->XSpline->DeepCopy(this->Spline);
  this->YSpline = this->Spline->NewInstance();
  this->YSpline->DeepCopy(this->Spline);
  this->ZSpline = this->Spline->NewInstance();
  this->ZSpline->DeepCopy(this->Spline);

  //  Create points along each polyline.
  //
  for (inCellId=0, inLines->InitTraversal();
       inLines->GetNextCell(npts,pts) && !abort; inCellId++)
    {
    this->UpdateProgress((double)inCellId/numLines);
    abort = this->GetAbortExecute();

    if (npts < 2)
      {
      vtkWarningMacro(<< "Less than two points in line!");
      continue; //skip tubing this polyline
      }

    // Generate the points around the polyline. The strip is not created
    // if the polyline is bad.
    //
    this->TCoordMap->Reset();
    numGenPts = this->GeneratePoints(offset, npts, pts, inPts, newPts,
                                     pd, outPD, genTCoords, newTCoords);
    if ( ! numGenPts )
      {
      vtkWarningMacro(<< "Could not generate points!");
      continue; //skip splining
      }

    // Generate the polyline
    //
    this->GenerateLine(offset,numGenPts,inCellId,cd,outCD,newLines);

    // Compute the new offset for the next polyline
    offset += numGenPts;

    }//for all polylines

  // Update ourselves
  //
  this->TCoordMap->Initialize();

  this->XSpline->Delete();
  this->YSpline->Delete();
  this->ZSpline->Delete();

  output->SetPoints(newPts);
  newPts->Delete();

  output->SetLines(newLines);
  newLines->Delete();

  if ( newTCoords )
    {
    outPD->SetTCoords(newTCoords);
    newTCoords->Delete();
    }

  output->Squeeze();

  return 1;
}

int vtkSplineFilter::GeneratePoints(vtkIdType offset, vtkIdType npts,
                                    vtkIdType *pts, vtkPoints *inPts,
                                    vtkPoints *newPts, vtkPointData *pd,
                                    vtkPointData *outPD, int genTCoords,
                                    vtkFloatArray *newTCoords)
{
  vtkIdType i;

  // Initialize the splines
  this->XSpline->RemoveAllPoints();
  this->YSpline->RemoveAllPoints();
  this->ZSpline->RemoveAllPoints();

  // Compute the length of the resulting spline
  double xPrev[3], x[3], length=0.0, len, t, tc;
  inPts->GetPoint(pts[0],xPrev);
  for (i=1; i < npts; i++)
    {
    inPts->GetPoint(pts[i],x);
    len = sqrt(vtkMath::Distance2BetweenPoints(x,xPrev));
    if ( len <= 0.0 )
      {
      return 0; //failure
      }
    length += len;
    xPrev[0]=x[0]; xPrev[1]=x[1]; xPrev[2]=x[2];
    }
  if ( length <= 0.0 )
    {
    return 0; //failure
    }

  // Now we insert points into the splines with the parametric coordinate
  // based on (polyline) length. We keep track of the parametric coordinates
  // of the points for later point interpolation.
  inPts->GetPoint(pts[0],xPrev);
  for (len=0,i=0; i < npts; i++)
    {
    inPts->GetPoint(pts[i],x);
    len += sqrt(vtkMath::Distance2BetweenPoints(x,xPrev));
    t = len/length;
    this->TCoordMap->InsertValue(i,t);

    this->XSpline->AddPoint(t,x[0]);
    this->YSpline->AddPoint(t,x[1]);
    this->ZSpline->AddPoint(t,x[2]);

    xPrev[0]=x[0]; xPrev[1]=x[1]; xPrev[2]=x[2];
    }

  // Compute the number of subdivisions
  vtkIdType numDivs, numNewPts;
  if ( this->Subdivide == VTK_SUBDIVIDE_SPECIFIED )
    {
    numDivs = this->NumberOfSubdivisions;
    }
  else
    {
    numDivs = (int) (length / this->Length);
    }
  numDivs = ( numDivs < 1 ? 1 : (numDivs > this->MaximumNumberOfSubdivisions ?
                                 this->MaximumNumberOfSubdivisions : numDivs));

  // Now compute the new points
  numNewPts = numDivs + 1;
  vtkIdType idx;
  double s, s0=0.0;
  if ( genTCoords == VTK_TCOORDS_FROM_SCALARS )
    {
    s0=pd->GetScalars()->GetTuple1(pts[0]);
    }
  double tLo = this->TCoordMap->GetValue(0);
  double tHi = this->TCoordMap->GetValue(1);
  for (idx=0, i=0; i < numNewPts; i++)
    {
    t = (double) i / numDivs;
    x[0] = this->XSpline->Evaluate(t);
    x[1] = this->YSpline->Evaluate(t);
    x[2] = this->ZSpline->Evaluate(t);
    newPts->InsertPoint(offset+i,x);

    // interpolate point data
    while ( t > tHi && idx < (npts-2))
      {
      idx++;
      tLo = this->TCoordMap->GetValue(idx);
      tHi = this->TCoordMap->GetValue(idx+1);
      }
    tc = (t - tLo) / (tHi - tLo);
    outPD->InterpolateEdge(pd,offset+i,pts[idx],pts[idx+1],tc);

    // generate texture coordinates if desired
    if ( genTCoords != VTK_TCOORDS_OFF )
      {
      if ( genTCoords == VTK_TCOORDS_FROM_NORMALIZED_LENGTH )
        {
        tc = t;
        }
      else if ( genTCoords == VTK_TCOORDS_FROM_LENGTH )
        {
        tc = t * length / this->TextureLength;
        }
      else if ( genTCoords == VTK_TCOORDS_FROM_SCALARS )
        {
        s = outPD->GetScalars()->GetTuple1(offset+i); //data just interpolated
        tc = (s - s0) / this->TextureLength;
        }
      newTCoords->InsertTuple2(offset+i,tc,0.0);
      } //if generating tcoords
    } //for all new points

  return numNewPts;
}

void vtkSplineFilter::GenerateLine(vtkIdType offset, vtkIdType npts,
                                   vtkIdType inCellId,
                                   vtkCellData *cd, vtkCellData *outCD,
                                   vtkCellArray *newLines)
{
  vtkIdType i, outCellId;

  outCellId = newLines->InsertNextCell(npts);
  outCD->CopyData(cd,inCellId,outCellId);
  for (i=0; i < npts; i++)
    {
    newLines->InsertCellPoint(offset+i);
    }
}

const char *vtkSplineFilter::GetSubdivideAsString()
{
  if ( this->Subdivide == VTK_SUBDIVIDE_SPECIFIED )
    {
    return "Specified by Number of Subdivisions";
    }
  else
    {
    return "Specified by Length";
    }
}

// Return the method of generating the texture coordinates.
const char *vtkSplineFilter::GetGenerateTCoordsAsString(void)
{
  if ( this->GenerateTCoords == VTK_TCOORDS_OFF )
    {
    return "GenerateTCoordsOff";
    }
  else if ( this->GenerateTCoords == VTK_TCOORDS_FROM_SCALARS )
    {
    return "GenerateTCoordsFromScalar";
    }
  else if ( this->GenerateTCoords == VTK_TCOORDS_FROM_LENGTH )
    {
    return "GenerateTCoordsFromLength";
    }
  else
    {
    return "GenerateTCoordsFromNormalizedLength";
    }
}

void vtkSplineFilter::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  os << indent << "Subdivide: :" << this->GetSubdivideAsString() << "\n";
  os << indent << "Maximum Number of Subdivisions: "
     << this->MaximumNumberOfSubdivisions << "\n";
  os << indent << "Number of Subdivisions: "
     << this->NumberOfSubdivisions << "\n";
  os << indent << "Length: " << this->Length << "\n";
  os << indent << "Spline: " << this->Spline << "\n";
  os << indent << "Generate TCoords: "
     << this->GetGenerateTCoordsAsString() << endl;
  os << indent << "Texture Length: " << this->TextureLength << endl;
}

<commit_msg>ENH: Do not produce warnings when source pt and target pt at the same place.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkSplineFilter.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkSplineFilter.h"

#include "vtkCardinalSpline.h"
#include "vtkCell.h"
#include "vtkCellArray.h"
#include "vtkCellData.h"
#include "vtkFloatArray.h"
#include "vtkMath.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkPolyData.h"

vtkCxxRevisionMacro(vtkSplineFilter, "1.18");
vtkStandardNewMacro(vtkSplineFilter);
vtkCxxSetObjectMacro(vtkSplineFilter,Spline,vtkSpline);

vtkSplineFilter::vtkSplineFilter()
{
  this->Subdivide = VTK_SUBDIVIDE_SPECIFIED;
  this->MaximumNumberOfSubdivisions = VTK_LARGE_INTEGER;
  this->NumberOfSubdivisions = 100;
  this->Length = 0.1;
  this->GenerateTCoords = VTK_TCOORDS_FROM_NORMALIZED_LENGTH;
  this->TextureLength = 1.0;

  this->Spline = vtkCardinalSpline::New();
  this->TCoordMap = vtkFloatArray::New();
}

vtkSplineFilter::~vtkSplineFilter()
{
  if (this->Spline)
    {
    this->Spline->Delete();
    this->Spline = 0;
    }

  if (this->TCoordMap)
    {
    this->TCoordMap->Delete();
    this->TCoordMap = 0;
    }
}

int vtkSplineFilter::RequestData(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **inputVector,
  vtkInformationVector *outputVector)
{
  // get the info objects
  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
  vtkInformation *outInfo = outputVector->GetInformationObject(0);

  // get the input and ouptut
  vtkPolyData *input = vtkPolyData::SafeDownCast(
    inInfo->Get(vtkDataObject::DATA_OBJECT()));
  vtkPolyData *output = vtkPolyData::SafeDownCast(
    outInfo->Get(vtkDataObject::DATA_OBJECT()));

  vtkPointData *pd=input->GetPointData();
  vtkPointData *outPD=output->GetPointData();
  vtkCellData *cd=input->GetCellData();
  vtkCellData *outCD=output->GetCellData();
  vtkCellArray *inLines;

  vtkPoints *inPts;
  vtkIdType numLines;
  vtkCellArray *newLines;
  vtkIdType numNewPts, numNewCells;
  vtkPoints *newPts;
  vtkIdType npts=0, *pts=NULL;
  vtkIdType offset=0;
  vtkFloatArray *newTCoords=NULL;
  int abort=0;
  vtkIdType inCellId, numGenPts;
  int genTCoords = VTK_TCOORDS_OFF;

  // Check input and initialize
  //
  vtkDebugMacro(<<"Splining polylines");

  if ( !(inPts=input->GetPoints()) || inPts->GetNumberOfPoints() < 1 ||
      !(inLines = input->GetLines()) ||
       (numLines = inLines->GetNumberOfCells()) < 1 )
    {
    vtkWarningMacro(<< " No input data!");
    return 1;
    }

  if ( this->Spline == NULL )
    {
    vtkWarningMacro(<< "Need to specify a spline!");
    return 1;
    }

  // Create the geometry and topology
  numNewPts = this->NumberOfSubdivisions * numLines;
  newPts = vtkPoints::New();
  newPts->Allocate(numNewPts);
  newLines = vtkCellArray::New();
  newLines->Allocate(newLines->EstimateSize(1,numNewPts));

  // Point data
  if ( (this->GenerateTCoords == VTK_TCOORDS_FROM_SCALARS &&
        pd->GetScalars() != NULL) ||
       (this->GenerateTCoords == VTK_TCOORDS_FROM_LENGTH ||
        this->GenerateTCoords == VTK_TCOORDS_FROM_NORMALIZED_LENGTH) )
    {
    genTCoords = this->GenerateTCoords;
    newTCoords = vtkFloatArray::New();
    newTCoords->SetNumberOfComponents(2);
    newTCoords->Allocate(numNewPts);
    outPD->CopyTCoordsOff();
    }
  outPD->InterpolateAllocate(pd,numNewPts);
  this->TCoordMap->Allocate(VTK_CELL_SIZE);

  // Copy cell data
  numNewCells = numLines;
  outCD->CopyNormalsOff();
  outCD->CopyAllocate(cd,numNewCells);

  // Set up the splines
  this->XSpline = this->Spline->NewInstance();
  this->XSpline->DeepCopy(this->Spline);
  this->YSpline = this->Spline->NewInstance();
  this->YSpline->DeepCopy(this->Spline);
  this->ZSpline = this->Spline->NewInstance();
  this->ZSpline->DeepCopy(this->Spline);

  //  Create points along each polyline.
  //
  for (inCellId=0, inLines->InitTraversal();
       inLines->GetNextCell(npts,pts) && !abort; inCellId++)
    {
    this->UpdateProgress((double)inCellId/numLines);
    abort = this->GetAbortExecute();

    if (npts < 2)
      {
      vtkWarningMacro(<< "Less than two points in line!");
      continue; //skip tubing this polyline
      }

    // Generate the points around the polyline. The strip is not created
    // if the polyline is bad.
    //
    this->TCoordMap->Reset();
    numGenPts = this->GeneratePoints(offset, npts, pts, inPts, newPts,
                                     pd, outPD, genTCoords, newTCoords);
    if ( ! numGenPts )
      {
      //vtkWarningMacro(<< "Could not generate points!");
      continue; //skip splining
      }

    // Generate the polyline
    //
    this->GenerateLine(offset,numGenPts,inCellId,cd,outCD,newLines);

    // Compute the new offset for the next polyline
    offset += numGenPts;

    }//for all polylines

  // Update ourselves
  //
  this->TCoordMap->Initialize();

  this->XSpline->Delete();
  this->YSpline->Delete();
  this->ZSpline->Delete();

  output->SetPoints(newPts);
  newPts->Delete();

  output->SetLines(newLines);
  newLines->Delete();

  if ( newTCoords )
    {
    outPD->SetTCoords(newTCoords);
    newTCoords->Delete();
    }

  output->Squeeze();

  return 1;
}

int vtkSplineFilter::GeneratePoints(vtkIdType offset, vtkIdType npts,
                                    vtkIdType *pts, vtkPoints *inPts,
                                    vtkPoints *newPts, vtkPointData *pd,
                                    vtkPointData *outPD, int genTCoords,
                                    vtkFloatArray *newTCoords)
{
  vtkIdType i;

  // Initialize the splines
  this->XSpline->RemoveAllPoints();
  this->YSpline->RemoveAllPoints();
  this->ZSpline->RemoveAllPoints();

  // Compute the length of the resulting spline
  double xPrev[3], x[3], length=0.0, len, t, tc;
  inPts->GetPoint(pts[0],xPrev);
  for (i=1; i < npts; i++)
    {
    inPts->GetPoint(pts[i],x);
    len = sqrt(vtkMath::Distance2BetweenPoints(x,xPrev));
    if ( len <= 0.0 )
      {
      return 0; //failure
      }
    length += len;
    xPrev[0]=x[0]; xPrev[1]=x[1]; xPrev[2]=x[2];
    }
  if ( length <= 0.0 )
    {
    return 0; //failure
    }

  // Now we insert points into the splines with the parametric coordinate
  // based on (polyline) length. We keep track of the parametric coordinates
  // of the points for later point interpolation.
  inPts->GetPoint(pts[0],xPrev);
  for (len=0,i=0; i < npts; i++)
    {
    inPts->GetPoint(pts[i],x);
    len += sqrt(vtkMath::Distance2BetweenPoints(x,xPrev));
    t = len/length;
    this->TCoordMap->InsertValue(i,t);

    this->XSpline->AddPoint(t,x[0]);
    this->YSpline->AddPoint(t,x[1]);
    this->ZSpline->AddPoint(t,x[2]);

    xPrev[0]=x[0]; xPrev[1]=x[1]; xPrev[2]=x[2];
    }

  // Compute the number of subdivisions
  vtkIdType numDivs, numNewPts;
  if ( this->Subdivide == VTK_SUBDIVIDE_SPECIFIED )
    {
    numDivs = this->NumberOfSubdivisions;
    }
  else
    {
    numDivs = (int) (length / this->Length);
    }
  numDivs = ( numDivs < 1 ? 1 : (numDivs > this->MaximumNumberOfSubdivisions ?
                                 this->MaximumNumberOfSubdivisions : numDivs));

  // Now compute the new points
  numNewPts = numDivs + 1;
  vtkIdType idx;
  double s, s0=0.0;
  if ( genTCoords == VTK_TCOORDS_FROM_SCALARS )
    {
    s0=pd->GetScalars()->GetTuple1(pts[0]);
    }
  double tLo = this->TCoordMap->GetValue(0);
  double tHi = this->TCoordMap->GetValue(1);
  for (idx=0, i=0; i < numNewPts; i++)
    {
    t = (double) i / numDivs;
    x[0] = this->XSpline->Evaluate(t);
    x[1] = this->YSpline->Evaluate(t);
    x[2] = this->ZSpline->Evaluate(t);
    newPts->InsertPoint(offset+i,x);

    // interpolate point data
    while ( t > tHi && idx < (npts-2))
      {
      idx++;
      tLo = this->TCoordMap->GetValue(idx);
      tHi = this->TCoordMap->GetValue(idx+1);
      }
    tc = (t - tLo) / (tHi - tLo);
    outPD->InterpolateEdge(pd,offset+i,pts[idx],pts[idx+1],tc);

    // generate texture coordinates if desired
    if ( genTCoords != VTK_TCOORDS_OFF )
      {
      if ( genTCoords == VTK_TCOORDS_FROM_NORMALIZED_LENGTH )
        {
        tc = t;
        }
      else if ( genTCoords == VTK_TCOORDS_FROM_LENGTH )
        {
        tc = t * length / this->TextureLength;
        }
      else if ( genTCoords == VTK_TCOORDS_FROM_SCALARS )
        {
        s = outPD->GetScalars()->GetTuple1(offset+i); //data just interpolated
        tc = (s - s0) / this->TextureLength;
        }
      newTCoords->InsertTuple2(offset+i,tc,0.0);
      } //if generating tcoords
    } //for all new points

  return numNewPts;
}

void vtkSplineFilter::GenerateLine(vtkIdType offset, vtkIdType npts,
                                   vtkIdType inCellId,
                                   vtkCellData *cd, vtkCellData *outCD,
                                   vtkCellArray *newLines)
{
  vtkIdType i, outCellId;

  outCellId = newLines->InsertNextCell(npts);
  outCD->CopyData(cd,inCellId,outCellId);
  for (i=0; i < npts; i++)
    {
    newLines->InsertCellPoint(offset+i);
    }
}

const char *vtkSplineFilter::GetSubdivideAsString()
{
  if ( this->Subdivide == VTK_SUBDIVIDE_SPECIFIED )
    {
    return "Specified by Number of Subdivisions";
    }
  else
    {
    return "Specified by Length";
    }
}

// Return the method of generating the texture coordinates.
const char *vtkSplineFilter::GetGenerateTCoordsAsString(void)
{
  if ( this->GenerateTCoords == VTK_TCOORDS_OFF )
    {
    return "GenerateTCoordsOff";
    }
  else if ( this->GenerateTCoords == VTK_TCOORDS_FROM_SCALARS )
    {
    return "GenerateTCoordsFromScalar";
    }
  else if ( this->GenerateTCoords == VTK_TCOORDS_FROM_LENGTH )
    {
    return "GenerateTCoordsFromLength";
    }
  else
    {
    return "GenerateTCoordsFromNormalizedLength";
    }
}

void vtkSplineFilter::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  os << indent << "Subdivide: :" << this->GetSubdivideAsString() << "\n";
  os << indent << "Maximum Number of Subdivisions: "
     << this->MaximumNumberOfSubdivisions << "\n";
  os << indent << "Number of Subdivisions: "
     << this->NumberOfSubdivisions << "\n";
  os << indent << "Length: " << this->Length << "\n";
  os << indent << "Spline: " << this->Spline << "\n";
  os << indent << "Generate TCoords: "
     << this->GetGenerateTCoordsAsString() << endl;
  os << indent << "Texture Length: " << this->TextureLength << endl;
}

<|endoftext|>


<commit_before>#include <stdio.h>

#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include "ExpertSystem/CLIPSEnvironment.h"
#include "ExpertSystem/KnowledgeConstructor.h"
#include "ExpertSystem/KnowledgeConstructionEngine.h"
#include "rampancy/RampancyCompiler.h"

extern "C" {
   #include "clips.h"
}

int main(int argc, char** argv, char* const *envp) {
   CLIPSEnvironment env;
   env.batchStar((char*)"Init.clp");
   env.eval((char*)"(set-current-module MAIN)");
   rampancy::Compiler compiler(env, envp);
   llvm::Module* mod = compiler.compile(argc, (const char**) argv);
   if(mod) {
      env.eval((char*)"(save-instances \"instances\" visible)");
   } else {
      env.eval((char*)"(printout t \"ERROR: Something went wrong\" crlf)");
   }
   llvm::llvm_shutdown();
}
<commit_msg>Modified the main function of main.cpp in kc to reference the ClangCompiler<commit_after>#include <stdio.h>

#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include "ExpertSystem/CLIPSEnvironment.h"
#include "ExpertSystem/KnowledgeConstructor.h"
#include "ExpertSystem/KnowledgeConstructionEngine.h"
#include "rampancy/Compiler.h"
#include "rampancy/ClangCompiler.h"

extern "C" {
   #include "clips.h"
}

int main(int argc, char** argv, char* const *envp) {
   CLIPSEnvironment env;
   env.batchStar((char*)"Init.clp");
   env.eval((char*)"(set-current-module MAIN)");
   rampancy::ClangCompiler compiler(env, envp);
   llvm::Module* mod = compiler.compile(argc, (const char**) argv);
   if(mod) {
      env.eval((char*)"(save-instances \"instances\" visible)");
   } else {
      env.eval((char*)"(printout t \"ERROR: Something went wrong\" crlf)");
   }
   llvm::llvm_shutdown();
}
<|endoftext|>


<commit_before>//===-- llc.cpp - Implement the LLVM Compiler -----------------------------===//
//
// This is the llc compiler driver.
//
//===----------------------------------------------------------------------===//

#include "llvm/Bytecode/Reader.h"
#include "llvm/Target/TargetMachineImpls.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Pass.h"
#include "Support/CommandLine.h"
#include "Support/Signals.h"
#include <memory>
#include <fstream>
#include <cstdio>

//------------------------------------------------------------------------------
// Option declarations for LLC.
//------------------------------------------------------------------------------

// General options for llc.  Other pass-specific options are specified
// within the corresponding llc passes, and target-specific options
// and back-end code generation options are specified with the target machine.
//
static cl::opt<std::string>
InputFilename(cl::Positional, cl::desc("<input bytecode>"), cl::init("-"));

static cl::opt<std::string>
OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"));

static cl::opt<bool> Force("f", cl::desc("Overwrite output files"));

enum ArchName { noarch, x86, Sparc };

static cl::opt<ArchName>
Arch("march", cl::desc("Architecture to generate assembly for:"), cl::Prefix,
     cl::values(clEnumVal(x86, "  IA-32 (Pentium and above)"),
		clEnumValN(Sparc, "sparc", "  SPARC V9"),
		0),
     cl::init(noarch));

// GetFileNameRoot - Helper function to get the basename of a filename...
static inline std::string
GetFileNameRoot(const std::string &InputFilename)
{
  std::string IFN = InputFilename;
  std::string outputFilename;
  int Len = IFN.length();
  if (IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') {
    outputFilename = std::string(IFN.begin(), IFN.end()-3); // s/.bc/.s/
  } else {
    outputFilename = IFN;
  }
  return outputFilename;
}

//===---------------------------------------------------------------------===//
// Function main()
//
// Entry point for the llc compiler.
//===---------------------------------------------------------------------===//

int
main(int argc, char **argv)
{
  cl::ParseCommandLineOptions(argc, argv, " llvm system compiler\n");

  // Load the module to be compiled...
  std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename));
  if (M.get() == 0)
    {
      std::cerr << argv[0] << ": bytecode didn't read correctly.\n";
      return 1;
    }
  Module &mod = *M.get();

  // Allocate target machine.  First, check whether the user has
  // explicitly specified an architecture to compile for.
  unsigned Config = (mod.isLittleEndian()   ? TM::LittleEndian : TM::BigEndian) |
                    (mod.has32BitPointers() ? TM::PtrSize32    : TM::PtrSize64);
  TargetMachine* (*TargetMachineAllocator)(unsigned) = 0;
  switch (Arch) {
  case x86:
    TargetMachineAllocator = allocateX86TargetMachine;
    break;
  case Sparc:
    TargetMachineAllocator = allocateSparcTargetMachine;
    break;
  default:
    // Decide what the default target machine should be, by looking at
    // the module. This heuristic (ILP32, LE -> IA32; LP64, BE ->
    // SPARCV9) is kind of gross, but it will work until we have more
    // sophisticated target information to work from.
    if (mod.isLittleEndian() && mod.has32BitPointers()) {
      TargetMachineAllocator = allocateX86TargetMachine;
    } else if (mod.isBigEndian() && mod.has64BitPointers()) {
      TargetMachineAllocator = allocateSparcTargetMachine;
    } else {
      assert(0 && "You must specify -march; I could not guess the default");
    }
    break;
  }
  std::auto_ptr<TargetMachine> target((*TargetMachineAllocator)(Config));
  assert(target.get() && "Could not allocate target machine!");
  TargetMachine &Target = *target.get();
  const TargetData &TD = Target.getTargetData();

  // Build up all of the passes that we want to do to the module...
  PassManager Passes;

  Passes.add(new TargetData("llc", TD.isLittleEndian(), TD.getPointerSize(),
                            TD.getPointerAlignment(), TD.getDoubleAlignment()));

  // Figure out where we are going to send the output...
  std::ostream *Out = 0;
  if (OutputFilename != "") {
    // Specified an output filename?
    if (!Force && std::ifstream(OutputFilename.c_str())) {
      // If force is not specified, make sure not to overwrite a file!
      std::cerr << argv[0] << ": error opening '" << OutputFilename
                << "': file exists!\n"
                << "Use -f command line argument to force output\n";
      return 1;
    }
    Out = new std::ofstream(OutputFilename.c_str());

    // Make sure that the Out file gets unlink'd from the disk if we get a
    // SIGINT
    RemoveFileOnSignal(OutputFilename);
  } else {
    if (InputFilename == "-") {
      OutputFilename = "-";
      Out = &std::cout;
    } else {
      OutputFilename = GetFileNameRoot(InputFilename);
      OutputFilename += ".s";

      if (!Force && std::ifstream(OutputFilename.c_str())) {
        // If force is not specified, make sure not to overwrite a file!
        std::cerr << argv[0] << ": error opening '" << OutputFilename
                  << "': file exists!\n"
                  << "Use -f command line argument to force output\n";
        return 1;
      }

      Out = new std::ofstream(OutputFilename.c_str());
      if (!Out->good()) {
        std::cerr << argv[0] << ": error opening " << OutputFilename << "!\n";
        delete Out;
        return 1;
      }

      // Make sure that the Out file gets unlink'd from the disk if we get a
      // SIGINT
      RemoveFileOnSignal(OutputFilename);
    }
  }

  // Ask the target to add backend passes as necessary
  if (Target.addPassesToEmitAssembly(Passes, *Out)) {
    std::cerr << argv[0] << ": target '" << Target.getName()
              << "' does not support static compilation!\n";
    if (Out != &std::cout) delete Out;
    // And the Out file is empty and useless, so remove it now.
    std::remove(OutputFilename.c_str());
    return 1;
  } else {
    // Run our queue of passes all at once now, efficiently.
    Passes.run(*M.get());
  }

  // Delete the ostream if it's not a stdout stream
  if (Out != &std::cout) delete Out;

  return 0;
}
<commit_msg>tools/llc/llc.cpp: Make "-o -" work.<commit_after>//===-- llc.cpp - Implement the LLVM Compiler -----------------------------===//
//
// This is the llc compiler driver.
//
//===----------------------------------------------------------------------===//

#include "llvm/Bytecode/Reader.h"
#include "llvm/Target/TargetMachineImpls.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Pass.h"
#include "Support/CommandLine.h"
#include "Support/Signals.h"
#include <memory>
#include <fstream>
#include <cstdio>

//------------------------------------------------------------------------------
// Option declarations for LLC.
//------------------------------------------------------------------------------

// General options for llc.  Other pass-specific options are specified
// within the corresponding llc passes, and target-specific options
// and back-end code generation options are specified with the target machine.
//
static cl::opt<std::string>
InputFilename(cl::Positional, cl::desc("<input bytecode>"), cl::init("-"));

static cl::opt<std::string>
OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"));

static cl::opt<bool> Force("f", cl::desc("Overwrite output files"));

enum ArchName { noarch, x86, Sparc };

static cl::opt<ArchName>
Arch("march", cl::desc("Architecture to generate assembly for:"), cl::Prefix,
     cl::values(clEnumVal(x86, "  IA-32 (Pentium and above)"),
		clEnumValN(Sparc, "sparc", "  SPARC V9"),
		0),
     cl::init(noarch));

// GetFileNameRoot - Helper function to get the basename of a filename...
static inline std::string
GetFileNameRoot(const std::string &InputFilename)
{
  std::string IFN = InputFilename;
  std::string outputFilename;
  int Len = IFN.length();
  if (IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') {
    outputFilename = std::string(IFN.begin(), IFN.end()-3); // s/.bc/.s/
  } else {
    outputFilename = IFN;
  }
  return outputFilename;
}

//===---------------------------------------------------------------------===//
// Function main()
//
// Entry point for the llc compiler.
//===---------------------------------------------------------------------===//

int
main(int argc, char **argv)
{
  cl::ParseCommandLineOptions(argc, argv, " llvm system compiler\n");

  // Load the module to be compiled...
  std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename));
  if (M.get() == 0)
    {
      std::cerr << argv[0] << ": bytecode didn't read correctly.\n";
      return 1;
    }
  Module &mod = *M.get();

  // Allocate target machine.  First, check whether the user has
  // explicitly specified an architecture to compile for.
  unsigned Config = (mod.isLittleEndian()   ? TM::LittleEndian : TM::BigEndian) |
                    (mod.has32BitPointers() ? TM::PtrSize32    : TM::PtrSize64);
  TargetMachine* (*TargetMachineAllocator)(unsigned) = 0;
  switch (Arch) {
  case x86:
    TargetMachineAllocator = allocateX86TargetMachine;
    break;
  case Sparc:
    TargetMachineAllocator = allocateSparcTargetMachine;
    break;
  default:
    // Decide what the default target machine should be, by looking at
    // the module. This heuristic (ILP32, LE -> IA32; LP64, BE ->
    // SPARCV9) is kind of gross, but it will work until we have more
    // sophisticated target information to work from.
    if (mod.isLittleEndian() && mod.has32BitPointers()) {
      TargetMachineAllocator = allocateX86TargetMachine;
    } else if (mod.isBigEndian() && mod.has64BitPointers()) {
      TargetMachineAllocator = allocateSparcTargetMachine;
    } else {
      assert(0 && "You must specify -march; I could not guess the default");
    }
    break;
  }
  std::auto_ptr<TargetMachine> target((*TargetMachineAllocator)(Config));
  assert(target.get() && "Could not allocate target machine!");
  TargetMachine &Target = *target.get();
  const TargetData &TD = Target.getTargetData();

  // Build up all of the passes that we want to do to the module...
  PassManager Passes;

  Passes.add(new TargetData("llc", TD.isLittleEndian(), TD.getPointerSize(),
                            TD.getPointerAlignment(), TD.getDoubleAlignment()));

  // Figure out where we are going to send the output...
  std::ostream *Out = 0;
  if (OutputFilename != "") {
    if (OutputFilename != "-") {
      // Specified an output filename?
      if (!Force && std::ifstream(OutputFilename.c_str())) {
	// If force is not specified, make sure not to overwrite a file!
	std::cerr << argv[0] << ": error opening '" << OutputFilename
		  << "': file exists!\n"
		  << "Use -f command line argument to force output\n";
	return 1;
      }
      Out = new std::ofstream(OutputFilename.c_str());

      // Make sure that the Out file gets unlink'd from the disk if we get a
      // SIGINT
      RemoveFileOnSignal(OutputFilename);
    } else {
      Out = &std::cout;
    }
  } else {
    if (InputFilename == "-") {
      OutputFilename = "-";
      Out = &std::cout;
    } else {
      OutputFilename = GetFileNameRoot(InputFilename);
      OutputFilename += ".s";

      if (!Force && std::ifstream(OutputFilename.c_str())) {
        // If force is not specified, make sure not to overwrite a file!
        std::cerr << argv[0] << ": error opening '" << OutputFilename
                  << "': file exists!\n"
                  << "Use -f command line argument to force output\n";
        return 1;
      }

      Out = new std::ofstream(OutputFilename.c_str());
      if (!Out->good()) {
        std::cerr << argv[0] << ": error opening " << OutputFilename << "!\n";
        delete Out;
        return 1;
      }

      // Make sure that the Out file gets unlink'd from the disk if we get a
      // SIGINT
      RemoveFileOnSignal(OutputFilename);
    }
  }

  // Ask the target to add backend passes as necessary
  if (Target.addPassesToEmitAssembly(Passes, *Out)) {
    std::cerr << argv[0] << ": target '" << Target.getName()
              << "' does not support static compilation!\n";
    if (Out != &std::cout) delete Out;
    // And the Out file is empty and useless, so remove it now.
    std::remove(OutputFilename.c_str());
    return 1;
  } else {
    // Run our queue of passes all at once now, efficiently.
    Passes.run(*M.get());
  }

  // Delete the ostream if it's not a stdout stream
  if (Out != &std::cout) delete Out;

  return 0;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <cmath>

using std::cin;
using std::cout;
using std::endl;
using std::string;

int menu();
double PowerDigitSum(double, double);

int main(int argc, char*argv[]){

	if (menu() == 1){
		double base, expo;
		cout << endl;

		cout << "Ingrese una base: ";
		cin >> base;

		cout << "Ingrese una potencia: ";
		cin >> expo;
		cout << endl;

		PowerDigitSum(base, expo);

	}else if (menu() == 2){
		cout << "prueba2";
	}else if (menu() == 3){
		cout << "prueba3";
	}

	return 0;
}

int menu(){
	int opcion;

	cout << "Programa #1 (16)" << endl
		<< "Porgrama #2 (21)" << endl
		<< "Programa #3(357)" << endl
		<< "Ingrese una opcion: ";
	cin >> opcion;

	return opcion;
}

double PowerDigitSum(double base, double expo){//no esta terminado
	double exponencial = pow(base, expo);

	cout << resultado;

	return resultado;
}

<commit_msg>ejercicio 16 completado<commit_after>#include <iostream>
#include <cmath>

using std::cin;
using std::cout;
using std::endl;
using std::string;

int menu();
int PowerDigitSum(int, int);

int main(int argc, char*argv[]){
	int opcion = menu();

	if (opcion == 1){
		int base, expo;
		cout << endl;

		cout << "Ingrese una base: ";
		cin >> base;

		cout << "Ingrese una potencia: ";
		cin >> expo;
		cout << endl;

		int resultado = PowerDigitSum(base, expo);

		cout << "El resultado del exponencial es: " << pow(base, expo) << endl;
		cout << "La suma de los digitos es: " << resultado << endl;

	}else if (opcion == 2){
		cout << "prueba2";
	}else if (opcion == 3){
		cout << "prueba3";
	}

	return 0;
}

int menu(){
	int opcion;

	cout << "Programa #1 (16)" << endl
		<< "Porgrama #2 (21)" << endl
		<< "Programa #3(357)" << endl
		<< "Ingrese una opcion: ";
	cin >> opcion;

	return opcion;
}

int PowerDigitSum(int base, int expo){//no esta terminado
	int exponencial = pow(base, expo);
	int aumentar = 1;
	int resultado = 0;
	int temp = 0;

	for (int i = 0; i < aumentar; i++){
		if (exponencial/10 != 0){
			aumentar++;
			resultado += exponencial%10;
			exponencial = exponencial/10;
		}else if (exponencial/10 == 0){
			resultado += exponencial;
		}
	}
	return resultado;
}

<|endoftext|>