コード例 #1
0
Point getClosestOnLine(Point from, Point p0, Point p1)
{
    Point direction = p1 - p0;
    Point toFrom = from-p0;
    int64_t projected_x = dot(toFrom, direction) ;

    int64_t x_p0 = 0;
    int64_t x_p1 = vSize2(direction);

    if (projected_x <= x_p0)
    {
        return p0;
    }
    if (projected_x >= x_p1)
    {
        return p1;
    }
    else
    {
        if (vSize2(direction) == 0)
        {
            std::cout << "warning! too small segment" << std::endl;
            return p0;
        }
        Point ret = p0 + projected_x / vSize(direction) * direction  / vSize(direction);
        return ret ;
    }

}
コード例 #2
0
void SparseGridTest::getNearestAssert(
    const std::vector<Point>& registered_points,
    Point target, const coord_t grid_size,
    Point* expected,
    const std::function<bool(const typename SparsePointGridInclusive<Point>::Elem& elem)> &precondition)
{
    SparsePointGridInclusive<Point> grid(grid_size);
    for (Point point : registered_points)
    {
        grid.insert(point, point);
    }

    typename SparsePointGridInclusive<Point>::Elem result;
    //The actual call to test.
    const bool success = grid.getNearest(target, grid_size,
                                         result, precondition);

    {
        std::stringstream ss;
        ss << "getNearest returned " << success <<
            " but should've returned " << (expected != nullptr) << ".";
        CPPUNIT_ASSERT_MESSAGE(ss.str(), success == (expected != nullptr));
    }
    if (expected)
    {
        std::stringstream ss;
        ss << "getNearest reported the nearest point to be " << result.val <<
            " (distance " << vSize(target - result.val) <<
            "), but it was " << *expected <<
            " (distance " << vSize(*expected - target) << ").";
        CPPUNIT_ASSERT_MESSAGE(ss.str(), result.val == *expected);
    }
}
コード例 #3
0
bool MergeInfillLines::isConvertible(unsigned int path_idx_first_move, Point& first_middle, Point& second_middle, int64_t& line_width, bool use_second_middle_as_first)
{
    int64_t max_line_width = nozzle_size * 3 / 2;
    
    
    unsigned int idx = path_idx_first_move;
    if (idx + 3 > paths.size()-1) return false;
    if (paths[idx+0].config != &travelConfig) return false;
    if (paths[idx+1].points.size() > 1) return false;
    if (paths[idx+1].config == &travelConfig) return false;
//                 if (paths[idx+2].points.size() > 1) return false;
    if (paths[idx+2].config != &travelConfig) return false;
    if (paths[idx+3].points.size() > 1) return false;
    if (paths[idx+3].config == &travelConfig) return false;
    
    Point& a = paths[idx+0].points.back(); // first extruded line from
    Point& b = paths[idx+1].points.back(); // first extruded line to
    Point& c = paths[idx+2].points.back(); // second extruded line from
    Point& d = paths[idx+3].points.back(); // second extruded line to
    Point ab = b - a;
    Point cd = d - c;
    
    int64_t prod = dot(ab,cd);
    if (std::abs(prod) + 400 < vSize(ab) * vSize(cd)) // 400 = 20*20, where 20 micron is the allowed inaccuracy in the dot product, introduced by the inaccurate point locations of a,b,c,d
        return false; // extrusion moves not in the same or opposite diraction
    if (prod < 0) { ab = ab * -1; }
    
    
    Point infill_vector = (cd + ab) / 2;
    
    if (!shorterThen(infill_vector, 5 * nozzle_size)) return false; // infill lines too far apart
                    
    first_middle = (use_second_middle_as_first)?
                    second_middle :
                    (a + b) / 2;
    second_middle = (c + d) / 2;
    
    Point dir_vector_perp = crossZ(second_middle - first_middle);
    int64_t dir_vector_perp_length = vSize(dir_vector_perp); // == dir_vector_length
    if (dir_vector_perp_length == 0) return false;
    if (dir_vector_perp_length > 5 * nozzle_size) return false; // infill lines too far apart
    
    
    line_width = std::abs( dot(dir_vector_perp, infill_vector) / dir_vector_perp_length );
    if (line_width > max_line_width) return false; // combined lines would be too wide
    if (line_width == 0) return false; // dot is zero, so lines are in each others extension, not next to eachother
    
    { // check whether the two lines are adjacent
        Point ca = first_middle - c;
        double ca_size = vSizeMM(ca);
        double cd_size = vSizeMM(cd);
        double prod = INT2MM(dot(ca, cd));
        double fraction = prod / ( ca_size * cd_size );
        int64_t line2line_dist = MM2INT(cd_size * std::sqrt(1.0 - fraction * fraction));
        
        if (line2line_dist + 20 > paths[idx+1].config->getLineWidth()) return false; // there is a gap between the two lines
    }
    
    return true;
};
コード例 #4
0
ファイル: comb.cpp プロジェクト: 976717326/CuraEngine
std::shared_ptr<std::pair<ClosestPolygonPoint, ClosestPolygonPoint>> Comb::findBestCrossing(PolygonRef from, Point estimated_start, Point estimated_end)
{
    ClosestPolygonPoint* best_in = nullptr;
    ClosestPolygonPoint* best_out = nullptr;
    int64_t best_detour_dist = std::numeric_limits<int64_t>::max();
    std::vector<std::pair<ClosestPolygonPoint, ClosestPolygonPoint>> crossing_out_candidates = PolygonUtils::findClose(from, getBoundaryOutside(), getOutsideLocToLine());
    for (std::pair<ClosestPolygonPoint, ClosestPolygonPoint>& crossing_candidate : crossing_out_candidates)
    {
        int64_t crossing_dist2 = vSize2(crossing_candidate.first.location - crossing_candidate.second.location);
        if (crossing_dist2 > max_crossing_dist2)
        {
            continue;
        }
        
        int64_t dist_to_start = vSize(crossing_candidate.second.location - estimated_start); // use outside location, so that the crossing direction is taken into account
        int64_t dist_to_end = vSize(crossing_candidate.second.location - estimated_end);
        int64_t detour_dist = dist_to_start + dist_to_end;
        if (detour_dist < best_detour_dist)
        {
            best_in = &crossing_candidate.first;
            best_out = &crossing_candidate.second;
            best_detour_dist = detour_dist;
        }
    }
    if (best_detour_dist == std::numeric_limits<int64_t>::max())
    {
        return std::shared_ptr<std::pair<ClosestPolygonPoint, ClosestPolygonPoint>>();
    }
    return std::make_shared<std::pair<ClosestPolygonPoint, ClosestPolygonPoint>>(*best_in, *best_out);
}
コード例 #5
0
ファイル: wallOverlap.cpp プロジェクト: HustLion/CuraEngine
void WallOverlapComputation::debugCheck()
{
    for (std::pair<WallOverlapPointLink, bool> pair : overlap_point_links)
    {
        if (std::abs(vSize( pair.first.a.p() - pair.first.b.p()) - pair.first.dist) > 10)
            DEBUG_PRINTLN(vSize( pair.first.a.p() - pair.first.b.p())<<" != " << pair.first.dist);
        
    }
}
コード例 #6
0
ファイル: wallOverlap.cpp プロジェクト: HustLion/CuraEngine
void WallOverlapComputation::addOverlapEndings()
{
//     for (WallOverlapPointLink& link : end_points)
//     {
//         // assume positive direction for a, negative for b
//         Loc2ListPolyIndex::iterator a_it_f = loc_to_list_poly_idx.find(link.a);
//         if (a_it_f == loc_to_list_poly_idx.end()) { DEBUG_PRINTLN(" ERROR:  cannot find point a!! "); }
//         ListPolygon::iterator a_it = a_it_f->second;
//         
//         Loc2ListPolyIndex::iterator b_it_f = loc_to_list_poly_idx.find(link.b);
//         if (b_it_f == loc_to_list_poly_idx.end()) { DEBUG_PRINTLN(" ERROR:  cannot find point b!! "); }
//         ListPolygon::iterator b_it = b_it_f->second;
//         
//         ListPolygon::iterator a_it_next = a_it;
//         a_it_next++;
//         if (a_it_next == 
//     }
    
//     for (ListPolygon& poly : list_polygons)
//     {
//         for (ListPolygon::iterator it = poly.begin(); it != poly.end(); ++it)
//         {
//             Point& p = *it;
//             
//         }
//     }
    for (std::pair<WallOverlapPointLink, bool> link_pair : overlap_point_links)
    {
        WallOverlapPointLink& link = link_pair.first;
        ListPolyIt a_next = link.a; ++a_next;
        ListPolyIt b_next = link.b; --b_next;
        Point& a1 = link.a.p();
        Point& a2 = a_next.p();
        Point& b1 = link.b.p();
        Point& b2 = b_next.p();
        Point a = a2-a1;
        Point b = b2-b1;
        if (point_to_link.find(a_next.p()) == point_to_link.end() 
            || point_to_link.find(b_next.p()) == point_to_link.end())
        {
            int64_t dist = overlapEndingDistance(a1, a2, b1, b2, link.dist);
            if (dist > 0)
            {
                Point a_p = a1 + a * dist / vSize(a);
                ListPolygon::iterator new_a = link.a.poly.insert(a_next.it, a_p);
                Point b_p = b1 + b * dist / vSize(b);
                ListPolygon::iterator new_b = link.a.poly.insert(link.b.it, b_p);
                addOverlapPoint(ListPolyIt(link.a.poly, new_a), ListPolyIt(link.b.poly, new_b), lineWidth);
            }
        }
        
        
        
    }
}
コード例 #7
0
ファイル: Comb.cpp プロジェクト: Robo3D/CuraEngine
std::shared_ptr<std::pair<ClosestPolygonPoint, ClosestPolygonPoint>> Comb::Crossing::findBestCrossing(const Polygons& outside, const PolygonRef from, const Point estimated_start, const Point estimated_end, Comb& comber)
{
    ClosestPolygonPoint* best_in = nullptr;
    ClosestPolygonPoint* best_out = nullptr;
    int64_t best_detour_score = std::numeric_limits<int64_t>::max();
    int64_t best_crossing_dist2;
    std::vector<std::pair<ClosestPolygonPoint, ClosestPolygonPoint>> crossing_out_candidates = PolygonUtils::findClose(from, outside, comber.getOutsideLocToLine());
    bool seen_close_enough_connection = false;
    for (std::pair<ClosestPolygonPoint, ClosestPolygonPoint>& crossing_candidate : crossing_out_candidates)
    {
        int64_t crossing_dist2 = vSize2(crossing_candidate.first.location - crossing_candidate.second.location);
        if (crossing_dist2 > comber.max_crossing_dist2 * 2)
        { // preliminary filtering
            continue;
        }
        
        int64_t dist_to_start = vSize(crossing_candidate.second.location - estimated_start); // use outside location, so that the crossing direction is taken into account
        int64_t dist_to_end = vSize(crossing_candidate.second.location - estimated_end);
        int64_t detour_dist = dist_to_start + dist_to_end;
        int64_t detour_score = crossing_dist2 + detour_dist * detour_dist / 1000; // prefer a closest connection over a detour
        // The detour distance is generally large compared to the crossing distance.
        // While the crossing is generally about 1mm across,
        // the distance between an arbitrary point and the boundary may well be a couple of centimetres.
        // So the crossing_dist2 is about 1.000.000 while the detour_dist_2 is in the order of 400.000.000
        // In the end we just want to choose between two points which have the _same_ crossing distance, modulo rounding error.
        if ((!seen_close_enough_connection && detour_score < best_detour_score) // keep the best as long as we havent seen one close enough (so that we may walk along the polygon to find a closer connection from it in the code below)
            || (!seen_close_enough_connection && crossing_dist2 <= comber.max_crossing_dist2) // make the one which is close enough the best as soon as we see one close enough
            || (seen_close_enough_connection && crossing_dist2 <= comber.max_crossing_dist2 && detour_score < best_detour_score)) // update to keep the best crossing which is close enough already
        {
            if (!seen_close_enough_connection && crossing_dist2 <= comber.max_crossing_dist2)
            {
                seen_close_enough_connection = true;
            }
            best_in = &crossing_candidate.first;
            best_out = &crossing_candidate.second;
            best_detour_score = detour_score;
            best_crossing_dist2 = crossing_dist2;
        }
    }
    if (best_detour_score == std::numeric_limits<int64_t>::max())
    { // i.e. if best_in == nullptr or if best_out == nullptr
        return std::shared_ptr<std::pair<ClosestPolygonPoint, ClosestPolygonPoint>>();
    }
    if (best_crossing_dist2 > comber.max_crossing_dist2)
    { // find closer point on line segments, rather than moving between vertices of the polygons only
        PolygonUtils::walkToNearestSmallestConnection(*best_in, *best_out);
        best_crossing_dist2 = vSize2(best_in->location - best_out->location);
        if (best_crossing_dist2 > comber.max_crossing_dist2)
        {
            return std::shared_ptr<std::pair<ClosestPolygonPoint, ClosestPolygonPoint>>();
        }
    }
    return std::make_shared<std::pair<ClosestPolygonPoint, ClosestPolygonPoint>>(*best_in, *best_out);
}
コード例 #8
0
void SparseGridTest::getNearbyAssert(
    const std::vector<Point>& registered_points,
    Point target, const coord_t grid_size,
    const std::unordered_set<Point>& expected_near,
    const std::unordered_set<Point>& expected_far)
{
    SparsePointGridInclusive<Point> grid(grid_size);
    for(Point point : registered_points)
    {
        grid.insert(point, point);
    }

    //The actual call to test.
    const std::vector<typename SparsePointGridInclusive<Point>::Elem> result =
        grid.getNearby(target, grid_size);

    //Are all near points reported as near?
    for (const Point point : expected_near)
    {
        std::stringstream ss;
        ss << "Point " << point << " is near " << target <<
            " (distance " << vSize(point - target) <<
            "), but getNearby didn't report it as such. Grid size: " <<
            grid_size;
        //Must be in result.
        CPPUNIT_ASSERT_MESSAGE(
            ss.str(),
            std::find_if(result.begin(), result.end(),
                         [&point](const typename SparsePointGridInclusive<Point>::Elem &elem)
                         {
                             return elem.val == point;
                         }) !=
            result.end());
    }
    //Are all far points NOT reported as near?
    for (const Point point : expected_far)
    {
        std::stringstream ss;
        ss << "Point " << point << " is far from " << target <<
            " (distance " << vSize(point - target) <<
            "), but getNearby thought it was near. Grid size: " << grid_size;
        //Must not be in result.
        CPPUNIT_ASSERT_MESSAGE(
            ss.str(),
            std::find_if(result.begin(), result.end(),
                         [&point](const typename SparsePointGridInclusive<Point>::Elem &elem)
                         {
                             return elem.val == point;
                         }) ==
            result.end());
    }
}
コード例 #9
0
void SparseGridTest::getNearbyLineTest()
{
    std::vector<Point> input;
    for (coord_t x = 0; x < 200; x++)
    {
        input.emplace_back(x, 95);
    }
    const Point target(100, 100);
    const coord_t grid_size = 10;
    std::unordered_set<Point> near;
    std::unordered_set<Point> far;
    for (const Point point : input)
    {
        coord_t distance = vSize(point - target);
        if (distance < grid_size)
        {
            near.insert(point);
        }
        else if (distance > grid_size * 2) //Grid size * 2 are guaranteed to be considered "far".
        {
            far.insert(point);
        }
    }
    getNearbyAssert(input, target, grid_size, near, far);
}
コード例 #10
0
void BucketGrid2DTest::findNearbyObjectsLineTest()
{
    std::vector<Point> input;
    for (long long x = 0; x < 200; x++)
    {
        input.emplace_back(x, 95);
    }
    const Point target(100, 100);
    const unsigned long long grid_size = 10;
    std::unordered_set<Point> near;
    std::unordered_set<Point> far;
    for (const Point point : input)
    {
        unsigned long long distance = vSize(point - target);
        if (distance < grid_size)
        {
            near.insert(point);
        }
        else if (distance > grid_size * 2) //Grid size * 2 are guaranteed to be considered "far".
        {
            far.insert(point);
        }
    }
    findNearbyObjectsAssert(input, target, grid_size, near, far);
}
コード例 #11
0
void PrimeTower::addPurgeMove(LayerPlan& gcode_layer, int extruder_nr, const ExtruderTrain *train, const Point& start_pos, const Point& end_pos, double purge_volume) const
{
    // Find out how much purging needs to be done.
    const GCodePathConfig& current_gcode_path_config = gcode_layer.configs_storage.prime_tower_config_per_extruder[extruder_nr];
    const coord_t purge_move_length = vSize(start_pos - end_pos);
    const unsigned int line_width = current_gcode_path_config.getLineWidth();
    const double layer_height_mm = (gcode_layer.getLayerNr() == 0) ? train->getSettingInMillimeters("layer_height_0") : train->getSettingInMillimeters("layer_height");
    const double normal_volume = INT2MM(INT2MM(purge_move_length * line_width)) * layer_height_mm; // Volume extruded on the "normal" move
    float purge_flow = purge_volume / normal_volume;

    const double purge_move_length_mm = INT2MM(purge_move_length);
    const double purge_move_time = purge_move_length_mm / current_gcode_path_config.getSpeed();
    const double purge_extrusion_speed_mm3_per_sec = purge_volume / purge_move_time;
    const double max_possible_extursion_speed_mm3_per_sec = 3.0;

    const double speed = current_gcode_path_config.getSpeed();
    double speed_factor = 1.0;

    if (purge_extrusion_speed_mm3_per_sec > max_possible_extursion_speed_mm3_per_sec)
    {
        // compensate the travel speed for the large extrusion amount
        const double min_time_needed_for_extrusion = purge_volume / max_possible_extursion_speed_mm3_per_sec;
        const double compensated_speed = purge_move_length_mm / min_time_needed_for_extrusion;
        speed_factor = compensated_speed / speed;
    }

    // As we need a plan, which can't have a stationary extrusion, we use an extrusion move to prime.
    // This has the added benefit that it will evenly spread the primed material inside the tower.
    gcode_layer.addExtrusionMove(end_pos, current_gcode_path_config, SpaceFillType::None, purge_flow, false, speed_factor);
}
コード例 #12
0
void LinearAlg2DTest::getPointOnLineWithDistAssert(const Point p, const Point a, const Point b, int64_t dist, Point actual_result, bool actual_returned)
{
    Point supposed_result;
    bool supposed_returned = LinearAlg2D::getPointOnLineWithDist(p, a, b, dist, supposed_result);

    int64_t returned_dist = vSize(supposed_result - p);

    std::stringstream ss;
    if (actual_returned)
    {
        if (supposed_returned)
        {
            ss << "Point " << p << " was projected on (" << a << "-" << b << ") to " << supposed_result << " instead of " << actual_result << ".";
        }
        else
        {
            ss << "Point " << p << " wasn't projected on (" << a << "-" << b << ") instead of projecting to " << actual_result << ".";
        }
    }
    else
    {
        if (supposed_returned)
        {
            ss << "Point " << p << " was projected on (" << a << "-" << b << ") to " << supposed_result << ", but it wasn't supposed to project.";
        }
        else
        {
            ss << "This is no error! This should never show!";
        }
    }
    ss << " \t Requested dist was " << dist << " result dist is " << returned_dist << ".";
    CPPUNIT_ASSERT_MESSAGE(ss.str(), (!actual_returned && !supposed_returned) || (actual_returned && vSize2(actual_result - supposed_result) < 10 * 10 && std::abs(returned_dist - dist) < 10));
}
コード例 #13
0
void FffPolygonGenerator::processFuzzyWalls(SliceMeshStorage& mesh)
{
    if (mesh.getSettingAsCount("wall_line_count") == 0)
    {
        return;
    }
    int64_t fuzziness = mesh.getSettingInMicrons("magic_fuzzy_skin_thickness");
    int64_t avg_dist_between_points = mesh.getSettingInMicrons("magic_fuzzy_skin_point_dist");
    int64_t min_dist_between_points = avg_dist_between_points * 3 / 4; // hardcoded: the point distance may vary between 3/4 and 5/4 the supplied value
    int64_t range_random_point_dist = avg_dist_between_points / 2;
    for (unsigned int layer_nr = 0; layer_nr < mesh.layers.size(); layer_nr++)
    {
        SliceLayer& layer = mesh.layers[layer_nr];
        for (SliceLayerPart& part : layer.parts)
        {
            Polygons results;
            Polygons& skin = (mesh.getSettingAsSurfaceMode("magic_mesh_surface_mode") == ESurfaceMode::SURFACE)? part.outline : part.insets[0];
            for (PolygonRef poly : skin)
            {
                // generate points in between p0 and p1
                PolygonRef result = results.newPoly();
                
                int64_t dist_left_over = rand() % (min_dist_between_points / 2); // the distance to be traversed on the line before making the first new point
                Point* p0 = &poly.back();
                for (Point& p1 : poly)
                { // 'a' is the (next) new point between p0 and p1
                    Point p0p1 = p1 - *p0;
                    int64_t p0p1_size = vSize(p0p1);    
                    int64_t dist_last_point = dist_left_over + p0p1_size * 2; // so that p0p1_size - dist_last_point evaulates to dist_left_over - p0p1_size
                    for (int64_t p0pa_dist = dist_left_over; p0pa_dist < p0p1_size; p0pa_dist += min_dist_between_points + rand() % range_random_point_dist)
                    {
                        int r = rand() % (fuzziness * 2) - fuzziness;
                        Point perp_to_p0p1 = turn90CCW(p0p1);
                        Point fuzz = normal(perp_to_p0p1, r);
                        Point pa = *p0 + normal(p0p1, p0pa_dist) + fuzz;
                        result.add(pa);
                        dist_last_point = p0pa_dist;
                    }
                    dist_left_over = p0p1_size - dist_last_point;
                    
                    p0 = &p1;
                }
                while (result.size() < 3 )
                {
                    unsigned int point_idx = poly.size() - 2;
                    result.add(poly[point_idx]);
                    if (point_idx == 0) { break; }
                    point_idx--;
                }
                if (result.size() < 3)
                {
                    result.clear();
                    for (Point& p : poly)
                        result.add(p);
                }
            }
            skin = results;
        }
    }
}
コード例 #14
0
bool wxStaticBox::Create( wxWindow*       pParent,
                          wxWindowID      vId,
                          const wxString& rsLabel,
                          const wxPoint&  rPos,
                          const wxSize&   rSize,
                          long            lStyle,
                          const wxString& rsName )
{
    if(!CreateControl( pParent
                      ,vId
                      ,rPos
                      ,rSize
                      ,lStyle
                      ,wxDefaultValidator
                      ,rsName
                     ))
    {
        return false;
    }

    wxPoint  vPos(0,0);
    wxSize   vSize(0,0);

    if (!OS2CreateControl( wxT("STATIC")
                          ,SS_GROUPBOX
                          ,vPos
                          ,vSize
                          ,rsLabel
                         ))
    {
        return false;
    }

    //
    // To be transparent we should have the same colour as the parent as well
    //
    SetBackgroundColour(GetParent()->GetBackgroundColour());

    LONG lColor = (LONG)wxBLACK->GetPixel();
    ::WinSetPresParam( m_hWnd
                      ,PP_FOREGROUNDCOLOR
                      ,sizeof(LONG)
                      ,(PVOID)&lColor
                     );

    lColor = (LONG)m_backgroundColour.GetPixel();
    ::WinSetPresParam( m_hWnd
                      ,PP_BACKGROUNDCOLOR
                      ,sizeof(LONG)
                      ,(PVOID)&lColor
                     );
    SetSize( rPos.x
            ,rPos.y
            ,rSize.x
            ,rSize.y
           );
    return true;
} // end of wxStaticBox::Create
コード例 #15
0
 coord_t MergeInfillLines::calcPathLength(const Point path_start, GCodePath& path) const
 {
     Point previous_point = path_start;
     coord_t result = 0;
     for (const Point point : path.points)
     {
         result += vSize(point - previous_point);
         previous_point = point;
     }
     return result;
 }
コード例 #16
0
/*
*  @brief
*    Create FBO
*/
bool SurfaceTextureBuffer::CreateFBO()
{
	// Get renderer
	Renderer &cRenderer = static_cast<Renderer&>(GetRenderer());

	// Get the depending of the texture buffer type
	PLRenderer::TextureBuffer *pTextureBuffer = static_cast<PLRenderer::TextureBuffer*>(m_cTextureBufferHandler.GetResource());
	if (pTextureBuffer) {
		// Get size
		Vector2i vSize(-1, -1);
		switch (pTextureBuffer->GetType()) {
			case PLRenderer::Resource::TypeTextureBuffer2D:
			{
				PLRenderer::TextureBuffer2D *pTextureBuffer2D = static_cast<PLRenderer::TextureBuffer2D*>(pTextureBuffer);
				vSize = pTextureBuffer2D->GetSize();
				break;
			}

			case PLRenderer::Resource::TypeTextureBufferCube:
			{
				PLRenderer::TextureBufferCube *pTextureBufferCube = static_cast<PLRenderer::TextureBufferCube*>(pTextureBuffer);
				const uint32 nSize = pTextureBufferCube->GetSize();
				vSize.x = vSize.y = nSize;
				break;
			}
		}
		if (vSize.x > 0 && vSize.y > 0) {
			// Initialize frame buffer
			m_pFrameBufferObject = new FrameBufferObject();
			uint32 nFormat = 0;
			// Depth buffer requested?
			if (m_nFlags & Depth)
				nFormat |= FrameBufferObject::Depth24;
			// Depth buffer only? (for instance for depth shadow mapping)
			if (pTextureBuffer->GetFormat() != PLRenderer::TextureBuffer::D16 && pTextureBuffer->GetFormat() != PLRenderer::TextureBuffer::D24 && pTextureBuffer->GetFormat() != PLRenderer::TextureBuffer::D32)
				nFormat |= FrameBufferObject::Color;
			// Stencil buffer requested?
			if (m_nFlags & Stencil)
				nFormat |= FrameBufferObject::Stencil;
			if (m_pFrameBufferObject->Initialize(cRenderer, vSize, nFormat, pTextureBuffer->GetFormat(), (m_nFlags & NoMultisampleAntialiasing) != 0)) {
				// Jipi, all went fine and we are still here! :)
				return true;
			} else {
				// D'OH!!
				delete m_pFrameBufferObject;
				m_pFrameBufferObject = nullptr;
			}
		}
	}

	// Error!
	return false;
}
コード例 #17
0
// -----------------------------------------------------------------------------
// CTestPlatAlfVisual::TestAlfLayoutSetAndGetL
// -----------------------------------------------------------------------------
//
TInt CTestPlatAlfVisual::TestAlfLayoutSetAndGetL( CStifItemParser& /*aItem*/ )
    {
    _LIT( KTestPlatAlfVisual, "TestPlatAlfVisual" );
    _LIT( KTestAlfLayoutSetAndGetL, "TestAlfLayoutSetAndGetL" );
    TestModuleIf().Printf( 0, KTestPlatAlfVisual, KTestAlfLayoutSetAndGetL );
    // Print to log file
    iLog->Log( KTestAlfLayoutSetAndGetL );
    
    CAlfLayout* vLayout = CAlfLayout::AddNewL( *iAlfCtl );
    CAlfImageVisual* vVisualOne = CAlfImageVisual::AddNewL( *iAlfCtl );
    TUid vUid = { 0x00000000 };
    TAlfImage vFirstImage( vUid, EAknsAppIconTypeList, 
            TSize( 1, 1), EAspectRatioPreserved, 0, 0, 0, 0 );
    vVisualOne->SetImage( vFirstImage );
    
    CAlfImageVisual* vVisualTwo = CAlfImageVisual::AddNewL( *iAlfCtl );
    TUid vSecUid = { 0x00000001 };
    TAlfImage vSecImage( vSecUid, EAknsAppIconTypeList, 
            TSize( 1, 1), EAspectRatioPreserved, 0, 0, 0, 0 );
    vVisualTwo->SetImage( vSecImage );
    
    vLayout->Append( vVisualOne );
    vLayout->Append( vVisualTwo );
    
    vLayout->EnableScrollingL();
    vLayout->Scrolling();
    TAlfTimedPoint vPoint( 0, 0 );
    vLayout->SetScrollOffset( vPoint );
    vLayout->ScrollOffset();
    TPoint vPos( 0, 1);
    TSize vSize( 1, 1 );
    vLayout->ChildOrdinal( 1 );
    vLayout->ChildPos( 0, vPos );
    vLayout->ChildSize( 0, vSize );
    
    TAlfXYMetric vXYMetric;
    vLayout->SetInnerPadding( vXYMetric );
    vLayout->InnerPaddingAsMetric();
    const TPoint vConstPos( 1, 1);
    vLayout->SetInnerPadding( vConstPos );
    vLayout->InnerPadding();
    vLayout->SetTransitionTime( 1 );
    
    vLayout->TransitionTime();
    vLayout->HorizontalInnerPadding();
    vLayout->VerticalInnerPadding();
    vLayout->InnerPaddingInBaseUnits();
    vLayout->EffectiveLayoutOrdinal( *vVisualTwo );
    
    return KErrNone;
    }
コード例 #18
0
ファイル: GameScriptParser.cpp プロジェクト: ChWick/Zelda
int addInvisibleBlockade(lua_State *l) {
    Ogre::Vector3 vPos(Ogre::StringConverter::parseVector3(lua_tostring(l, 1)));
    Ogre::Vector3 vSize(Ogre::StringConverter::parseVector3(lua_tostring(l, 2)));

    btRigidBody::btRigidBodyConstructionInfo rbConstruction(0, new btDefaultMotionState(), new btBoxShape(BtOgre::Convert::toBullet(vSize)));
    btRigidBody *pRB = new btRigidBody(rbConstruction);
    pRB->setWorldTransform(btTransform(btQuaternion::getIdentity(), BtOgre::Convert::toBullet(vPos)));

    GameScriptParser::getSingleton().getMap()->getPhysicsManager()->getWorld()->addRigidBody(pRB, COL_WALL, MASK_BLOCKADE_COLLIDES_WITH);


    lua_pushinteger(l, GameScriptParser::getSingleton().addPointerToMap(pRB, GameScriptParser::UserPointerData::RIGID_BODY));
    return 1;
}
コード例 #19
0
void SparseGridTest::getNearestEqualTest()
{
    std::vector<Point> registered_points;
    registered_points.emplace_back(95, 100);
    registered_points.emplace_back(105, 100);
    Point target = Point(100, 100);
    const coord_t grid_size = 10;
    const Point expected1 = Point(95, 100);
    const Point expected2 = Point(105, 100);

    SparsePointGridInclusive<Point> grid(grid_size);
    for (Point point : registered_points)
    {
        grid.insert(point, point);
    }

    typename SparsePointGridInclusive<Point>::Elem result;
    //The actual call to test.
    const bool success = grid.getNearest(target, grid_size,
                                         result, SparsePointGridInclusive<Point>::no_precondition);

    {
        std::stringstream ss;
        ss << "getNearest returned " << success << " but should've returned true.";
        CPPUNIT_ASSERT_MESSAGE(ss.str(), success);
    }
    {
        std::stringstream ss;
        ss << "getNearest reported the nearest point to be " << result.val <<
            " (distance " << vSize(target - result.val) <<
            "), but it should've been " << expected1 <<
            " (distance " << vSize(expected1 - target) <<
            ") or " << expected2 <<
            " (distance " << vSize(expected2 - target) << ").";
        CPPUNIT_ASSERT_MESSAGE(ss.str(), result.val == expected1 || result.val == expected2);
    }
}
コード例 #20
0
void BucketGrid2DTest::findNearbyObjectsAssert(const std::vector<Point>& registered_points, Point target, const unsigned long long grid_size, const std::unordered_set<Point>& expected_near, const std::unordered_set<Point>& expected_far)
{
    BucketGrid2D<Point> grid(grid_size);
    for(Point point : registered_points)
    {
        grid.insert(point, point);
    }

    const std::vector<Point> result = grid.findNearbyObjects(target); //The actual call to test.

    //Note that the result may contain the same point more than once. This test is robust against that.
    for (const Point point : expected_near) //Are all near points reported as near?
    {
        std::stringstream ss;
        ss << "Point " << point << " is near " << target << " (distance " << vSize(point - target) << "), but findNearbyObjects didn't report it as such. Grid size: " << grid_size;
        CPPUNIT_ASSERT_MESSAGE(ss.str(), std::find(result.begin(), result.end(), point) != result.end()); //Must be in result.
    }
    for (const Point point : expected_far) //Are all far points NOT reported as near?
    {
        std::stringstream ss;
        ss << "Point " << point << " is far from " << target << " (distance " << vSize(point - target) << "), but findNearbyObjects thought it was near. Grid size: " << grid_size;
        CPPUNIT_ASSERT_MESSAGE(ss.str(), std::find(result.begin(), result.end(), point) == result.end()); //Must not be in result.
    }
}
コード例 #21
0
ファイル: utils.cpp プロジェクト: lemahdi/mglib
	/* converting a CellMatrix of interpolation types to a sid::vector<int> */
	vector<int> FromCellMatrixToInterpolVector(const CellMatrix& aCM)
	{
		if (aCM.Size() > maxInterpoltypesNb)
		{
			ostringstream vOs;
			vOs << "Maximum number of interpolations is " << maxInterpoltypesNb << ", please advise.";
			MG_THROW(vOs.str());
		}
		vector<string> vInterpolTypesStr = FromCellMatrixToVectorStr(aCM);
		size_t vSize(vInterpolTypesStr.size());
		vector<int> vInterpolTypesInt(vSize);
		for(size_t i=0; i<vSize; ++i)
			vInterpolTypesInt[i] = InterpolMethodConvertor[vInterpolTypesStr[i]];
		return vInterpolTypesInt;
	}
コード例 #22
0
ファイル: ext-opencl.cpp プロジェクト: coinhelper/coin
vector<ProgramBinary> Program::get_Binaries() {
	vector<ProgramBinary> r;

	vector<Device> devs = Devices;
	if (cl_uint n = devs.size()) {
		vector<size_t> vSize(n);
		ClCheck(::clGetProgramInfo(Handle(), CL_PROGRAM_BINARY_SIZES, sizeof(size_t)*n, &vSize[0], 0));
		r.resize(n);
		vector<void*> vp(n);
		for (int i=0; i<n; ++i) {
			r[i].Device = devs[i];
			r[i].Binary.Size = vSize[i];
			vp[i] = r[i].Binary.data();
		}
		ClCheck(::clGetProgramInfo(Handle(), CL_PROGRAM_BINARIES,	sizeof(void*)*n, &vp[0], 0));
	}
	return r;
}
コード例 #23
0
ファイル: comb.cpp プロジェクト: GregFrost/CuraEngine
bool Comb::moveInside(Point* p, int distance)
{
    Point ret = *p;
    int64_t bestDist = MM2INT(2.0) * MM2INT(2.0);
    for(unsigned int n=0; n<boundery.size(); n++)
    {
        if (boundery[n].size() < 1)
            continue;
        Point p0 = boundery[n][boundery[n].size()-1];
        for(unsigned int i=0; i<boundery[n].size(); i++)
        {
            Point p1 = boundery[n][i];
            
            //Q = A + Normal( B - A ) * ((( B - A ) dot ( P - A )) / VSize( A - B ));
            Point pDiff = p1 - p0;
            int64_t lineLength = vSize(pDiff);
            int64_t distOnLine = dot(pDiff, *p - p0) / lineLength;
            if (distOnLine < 10)
                distOnLine = 10;
            if (distOnLine > lineLength - 10)
                distOnLine = lineLength - 10;
            Point q = p0 + pDiff * distOnLine / lineLength;
            
            int64_t dist = vSize2(q - *p);
            if (dist < bestDist)
            {
                bestDist = dist;
                ret = q + crossZ(normal(p1 - p0, distance));
            }
            
            p0 = p1;
        }
    }
    if (bestDist < MM2INT(2.0) * MM2INT(2.0))
    {
        *p = ret;
        return true;
    }
    return false;
}
コード例 #24
0
void Selene::CDefaultApplication::Render(float fDeltaTime)
{
	Vector2 vSize(200.0f, 200.0f);
	Vector2 vPos(400.0f, 300.0f);

	float afCoords[8] = 
	{
		-vSize.x * 0.5f, -vSize.y * 0.5f,
		vSize.x * 0.5f, -vSize.y * 0.5f,
		vSize.x * 0.5f, vSize.y * 0.5f,
		-vSize.x * 0.5f, vSize.y * 0.5f,
	};

//	elfQuads_begin();
//	// format - argb
//	elfQuads_setColour(0xffff4080);
////	elfQuads_setTextureRectangle(0.0f, 0.0f, 1.0f, 1.0f);
////	elfQuads_drawRectangleCentered(m_fPosX, m_fPosY, m_fSizeWidth, m_fSizeHeight);
//	//elfQuads_drawRectangle(fStartX, fStartY, fEndX, fEndY);
//	elfQuads_drawShapeOffset(vPos.x, vPos.y, afCoords);
//	elfQuads_end();
}
コード例 #25
0
ファイル: wallOverlap.cpp プロジェクト: gsmith-to/CuraEngine
float WallOverlapComputation::getFlow(const Point& from, const Point& to)
{
    using Point2LinkIt = PolygonProximityLinker::Point2Link::iterator;

    if (!overlap_linker.isLinked(from))
    { // [from] is not linked
        return 1;
    }
    const std::pair<Point2LinkIt, Point2LinkIt> to_links = overlap_linker.getLinks(to);
    if (to_links.first == to_links.second)
    { // [to] is not linked
        return 1;
    }

    int64_t overlap_area = 0;
    // note that we don't need to loop over all from_links, because they are handled in the previous getFlow(.) call (or in the very last)
    for (Point2LinkIt to_link_it = to_links.first; to_link_it != to_links.second; ++to_link_it)
    {
        const ProximityPointLink& to_link = to_link_it->second;
        ListPolyIt to_it = to_link.a;
        ListPolyIt to_other_it = to_link.b;
        if (to_link.a.p() != to)
        {
            assert(to_link.b.p() == to && "Either part of the link should be the point in the link!");
            std::swap(to_it, to_other_it);
        }
        ListPolyIt from_it = to_it.prev();

        if (from_it.p() != from)
        {
            logWarning("Polygon has multiple verts at the same place: (%lli, %lli); PolygonProximityLinker fails in such a case!\n", from.X, from.Y);
        }

        ListPolyIt to_other_next_it = to_other_it.next(); // move towards [from]; the lines on the other side move in the other direction
        //           to  from
        //   o<--o<--T<--F
        //   |       :   :
        //   v       :   :
        //   o-->o-->o-->o
        //           ,   ,
        //           ;   to_other_next
        //           to other

        bool are_in_same_general_direction = dot(from - to, to_other_it.p() - to_other_next_it.p()) > 0;
        // handle multiple points  linked to [to]
        //   o<<<T<<<F
        //     / |
        //    /  |
        //   o>>>o>>>o
        //   ,   ,
        //   ;   to other next
        //   to other
        if (!are_in_same_general_direction)
        {
            overlap_area = std::max(overlap_area, handlePotentialOverlap(to_it, to_it, to_link, to_other_next_it, to_other_it));
        }

        // handle multiple points  linked to [to_other]
        //   o<<<T<<<F
        //       |  /
        //       | /
        //   o>>>o>>>o
        bool all_are_in_same_general_direction = are_in_same_general_direction && dot(from - to, to_other_it.prev().p() - to_other_it.p()) > 0;
        if (!all_are_in_same_general_direction)
        {
            overlap_area = std::max(overlap_area, handlePotentialOverlap(from_it, to_it, to_link, to_other_it, to_other_it));
        }

        // handle normal case where the segment from-to overlaps with another segment
        //   o<<<T<<<F
        //       |   |
        //       |   |
        //   o>>>o>>>o
        //       ,   ,
        //       ;   to other next
        //       to other
        if (!are_in_same_general_direction)
        {
            overlap_area = std::max(overlap_area, handlePotentialOverlap(from_it, to_it, to_link, to_other_next_it, to_other_it));
        }
    }

    int64_t normal_area = vSize(from - to) * line_width;
    float ratio = float(normal_area - overlap_area) / normal_area;
    // clamp the ratio because overlap compensation might be faulty because
    // WallOverlapComputation::getApproxOverlapArea only gives roughly accurate results
    return std::min(1.0f, std::max(0.0f, ratio));
}
コード例 #26
0
ファイル: wallOverlap.cpp プロジェクト: gsmith-to/CuraEngine
int64_t WallOverlapComputation::getApproxOverlapArea(const Point from, const Point to, const int64_t to_dist, const Point other_from, const Point other_to, const int64_t from_dist)
{
    const int64_t overlap_width_2 = line_width * 2 - from_dist - to_dist; //Twice the width of the overlap area, perpendicular to the lines.

    // check whether the line segment overlaps with the point if one of the line segments is just a point
    if (from == to)
    {
        if (LinearAlg2D::pointIsProjectedBeyondLine(from, other_from, other_to) != 0)
        {
            return 0;
        }
        const int64_t overlap_length_2 = vSize(other_to - other_from); //Twice the length of the overlap area, alongside the lines.
        return overlap_length_2 * overlap_width_2 / 4; //Area = width * height.
    }
    if (other_from == other_to)
    {
        if (LinearAlg2D::pointIsProjectedBeyondLine(other_from, from, to) != 0)
        {
            return 0;
        }
        const int64_t overlap_length_2 = vSize(from - to); //Twice the length of the overlap area, alongside the lines.
        return overlap_length_2 * overlap_width_2 / 4; //Area = width * height.
    }

    short from_rel = LinearAlg2D::pointIsProjectedBeyondLine(from, other_from, other_to);
    short to_rel = LinearAlg2D::pointIsProjectedBeyondLine(to, other_from, other_to);
    short other_from_rel = LinearAlg2D::pointIsProjectedBeyondLine(other_from, from, to);
    short other_to_rel = LinearAlg2D::pointIsProjectedBeyondLine(other_to, from, to);
    if (from_rel != 0 && to_rel == from_rel && other_from_rel != 0 && other_to_rel == other_from_rel)
    {
        // both segments project fully beyond or before each other
        // for example:             or:
        // O<------O   .            O------>O
        //         :   :                     \_
        //         '   O------->O             O------>O
        return 0;
    }

    if (from_rel != 0 && from_rel == other_from_rel && to_rel == 0 && other_to_rel == 0)
    {
        // only ends of line segments overlap
        //
        //       to_proj
        //         ^^^^^
        //         O<--+----O
        //         :   :
        //   O-----+-->O
        //         ,,,,,
        //         other_to_proj
        const Point other_vec = other_from - other_to;
        const int64_t to_proj = dot(to - other_to, other_vec) / vSize(other_vec);

        const Point vec = from - to;
        const int64_t other_to_proj = dot(other_to - to, vec) / vSize(vec);

        const int64_t overlap_length_2 = to_proj + other_to_proj; //Twice the length of the overlap area, alongside the lines.
        return overlap_length_2 * overlap_width_2 / 4; //Area = width * height.
    }
    if (to_rel != 0 && to_rel == other_to_rel && from_rel == 0 && other_from_rel == 0)
    {
        // only beginnings of line segments overlap
        //
        //           from_proj
        //           ^^^^^
        //      O<---+---O
        //           :   :
        //           O---+---->O
        //           ,,,,,
        // other_from_proj
        const Point other_vec = other_to - other_from;
        const int64_t from_proj = dot(from - other_from, other_vec) / vSize(other_vec);

        const Point vec = to - from;
        const int64_t other_from_proj = dot(other_from - from, vec) / vSize(vec);

        const int64_t overlap_length_2 = from_proj + other_from_proj; //Twice the length of the overlap area, alongside the lines.
        return overlap_length_2 * overlap_width_2 / 4; //Area = width * height.
    }

    //More complex case.
    const Point from_middle = other_to + from; // don't divide by two just yet
    const Point to_middle = other_from + to; // don't divide by two just yet

    const int64_t overlap_length_2 = vSize(from_middle - to_middle); //(An approximation of) twice the length of the overlap area, alongside the lines.
    return overlap_length_2 * overlap_width_2 / 4; //Area = width * height.
}
コード例 #27
0
bool MergeInfillLines::isConvertible(const Point& a, const Point& b, const Point& c, const Point& d, int64_t line_width, Point& first_middle, Point& second_middle, int64_t& resulting_line_width, bool use_second_middle_as_first)
{
    use_second_middle_as_first = false;
    int64_t nozzle_size = line_width; // TODO
    int64_t max_line_width = nozzle_size * 3 / 2;

    Point ab = b - a;
    Point cd = d - c;

    if (b == c)
    {
        return false; // the line segments are connected!
    }

    int64_t ab_size = vSize(ab);
    int64_t cd_size = vSize(cd);

    if (ab_size > nozzle_size * 5 || cd_size > nozzle_size * 5)
    {
        return false; // infill lines are too long; otherwise infill lines might be merged when the next infill line is coincidentally shorter like |, would become \ ...
    }

    // if the lines are in the same direction then abs( dot(ab,cd) / |ab| / |cd| ) == 1
    int64_t prod = dot(ab,cd);
    if (std::abs(prod) + 400 < ab_size * cd_size) // 400 = 20*20, where 20 micron is the allowed inaccuracy in the dot product, introduced by the inaccurate point locations of a,b,c,d
        return false; // extrusion moves not in the same or opposite diraction
    
    // make lines in the same direction by flipping one
    if (prod < 0)
    {
        ab = ab * -1;
    }
    else if (prod == 0)
    {
        return false; // lines are orthogonal!
    }
    else if (b == d || a == c)
    {
        return false; // the line segments are connected!
    }

    first_middle = (use_second_middle_as_first)?
                    second_middle :
                    (a + b) / 2;
    second_middle = (c + d) / 2;
    
    Point dir_vector_perp = crossZ(second_middle - first_middle);
    int64_t dir_vector_perp_length = vSize(dir_vector_perp); // == dir_vector_length
    if (dir_vector_perp_length == 0) return false;
    if (dir_vector_perp_length > 5 * nozzle_size) return false; // infill lines too far apart

    Point infill_vector = (cd + ab) / 2; // (similar to) average line / direction of the infill

    // compute the resulting line width
    resulting_line_width = std::abs( dot(dir_vector_perp, infill_vector) / dir_vector_perp_length );
    if (resulting_line_width > max_line_width) return false; // combined lines would be too wide
    if (resulting_line_width == 0) return false; // dot is zero, so lines are in each others extension, not next to eachother

    // check whether two lines are adjacent (note: not 'line segments' but 'lines')
    Point ac = c - first_middle;
    Point infill_vector_perp = crossZ(infill_vector);
    int64_t perp_proj = dot(ac, infill_vector_perp);
    int64_t infill_vector_perp_length = vSize(infill_vector_perp);
    if (std::abs(std::abs(perp_proj) / infill_vector_perp_length - line_width) > 20) // it should be the case that dot(ac, infill_vector_perp) / |infill_vector_perp| == line_width
    {
        return false; // lines are too far apart or too close together
    }
    
    // check whether the two line segments are adjacent.
    // full infill in a narrow area might result in line segments with arbitrary distance between them
    // the more the narrow passage in the area gets aligned with the infill direction, the further apart the line segments will be
    // however, distant line segments might also be due to different narrow passages, so we limit the distance between merged line segments.
    if (!LinearAlg2D::lineSegmentsAreCloserThan(a, b, c, d, line_width * 2))
    {
        return false;
    }

    return true;
};
コード例 #28
0
ファイル: slicer.cpp プロジェクト: ubaldino/SawersPrinter3D
void SlicerLayer::makePolygons(OptimizedVolume* ov, bool keepNoneClosed, bool extensiveStitching)
{
    for(unsigned int startSegment=0; startSegment < segmentList.size(); startSegment++)
    {
        if (segmentList[startSegment].addedToPolygon)
            continue;
        
        ClipperLib::Polygon poly;
        poly.push_back(segmentList[startSegment].start);
        
        unsigned int segmentIndex = startSegment;
        bool canClose;
        while(true)
        {
            canClose = false;
            segmentList[segmentIndex].addedToPolygon = true;
            Point p0 = segmentList[segmentIndex].end;
            poly.push_back(p0);
            int nextIndex = -1;
            OptimizedFace* face = &ov->faces[segmentList[segmentIndex].faceIndex];
            for(unsigned int i=0;i<3;i++)
            {
                if (face->touching[i] > -1 && faceToSegmentIndex.find(face->touching[i]) != faceToSegmentIndex.end())
                {
                    Point p1 = segmentList[faceToSegmentIndex[face->touching[i]]].start;
                    Point diff = p0 - p1;
                    if (shorterThen(diff, 10))
                    {
                        if (faceToSegmentIndex[face->touching[i]] == (int)startSegment)
                            canClose = true;
                        if (segmentList[faceToSegmentIndex[face->touching[i]]].addedToPolygon)
                            continue;
                        nextIndex = faceToSegmentIndex[face->touching[i]];
                    }
                }
            }
            if (nextIndex == -1)
                break;
            segmentIndex = nextIndex;
        }
        if (canClose)
            polygonList.add(poly);
        else
            openPolygonList.add(poly);
    }
    //Clear the segmentList to save memory, it is no longer needed after this point.
    segmentList.clear();

    //Connecting polygons that are not closed yet, as models are not always perfect manifold we need to join some stuff up to get proper polygons
    //First link up polygon ends that are within 2 microns.
    for(unsigned int i=0;i<openPolygonList.size();i++)
    {
        if (openPolygonList[i].size() < 1) continue;
        for(unsigned int j=0;j<openPolygonList.size();j++)
        {
            if (openPolygonList[j].size() < 1) continue;
            
            Point diff = openPolygonList[i][openPolygonList[i].size()-1] - openPolygonList[j][0];
            int64_t distSquared = vSize2(diff);

            if (distSquared < 2 * 2)
            {
                if (i == j)
                {
                    polygonList.add(openPolygonList[i]);
                    openPolygonList[i].clear();
                    break;
                }else{
                    for(unsigned int n=0; n<openPolygonList[j].size(); n++)
                        openPolygonList[i].push_back(openPolygonList[j][n]);

                    openPolygonList[j].clear();
                }
            }
        }
    }
    
    //Next link up all the missing ends, closing up the smallest gaps first. This is an inefficient implementation which can run in O(n*n*n) time.
    while(1)
    {
        int64_t bestScore = 10000 * 10000;
        unsigned int bestA = -1;
        unsigned int bestB = -1;
        bool reversed = false;
        for(unsigned int i=0;i<openPolygonList.size();i++)
        {
            if (openPolygonList[i].size() < 1) continue;
            for(unsigned int j=0;j<openPolygonList.size();j++)
            {
                if (openPolygonList[j].size() < 1) continue;
                
                Point diff = openPolygonList[i][openPolygonList[i].size()-1] - openPolygonList[j][0];
                int64_t distSquared = vSize2(diff);
                if (distSquared < bestScore)
                {
                    bestScore = distSquared;
                    bestA = i;
                    bestB = j;
                    reversed = false;
                }

                if (i != j)
                {
                    Point diff = openPolygonList[i][openPolygonList[i].size()-1] - openPolygonList[j][openPolygonList[j].size()-1];
                    int64_t distSquared = vSize2(diff);
                    if (distSquared < bestScore)
                    {
                        bestScore = distSquared;
                        bestA = i;
                        bestB = j;
                        reversed = true;
                    }
                }
            }
        }
        
        if (bestScore >= 10000 * 10000)
            break;
        
        if (bestA == bestB)
        {
            polygonList.add(openPolygonList[bestA]);
            openPolygonList[bestA].clear();
        }else{
            if (reversed)
            {
                for(unsigned int n=openPolygonList[bestB].size()-1; int(n)>=0; n--)
                    openPolygonList[bestA].push_back(openPolygonList[bestB][n]);
            }else{
                for(unsigned int n=0; n<openPolygonList[bestB].size(); n++)
                    openPolygonList[bestA].push_back(openPolygonList[bestB][n]);
            }

            openPolygonList[bestB].clear();
        }
    }

    if (extensiveStitching)
    {
        //For extensive stitching find 2 open polygons that are touching 2 closed polygons.
        // Then find the sortest path over this polygon that can be used to connect the open polygons,
        // And generate a path over this shortest bit to link up the 2 open polygons.
        // (If these 2 open polygons are the same polygon, then the final result is a closed polyon)
        
        while(1)
        {
            unsigned int bestA = -1;
            unsigned int bestB = -1;
            gapCloserResult bestResult;
            bestResult.len = LLONG_MAX;
            bestResult.polygonIdx = -1;
            bestResult.pointIdxA = -1;
            bestResult.pointIdxB = -1;
            
            for(unsigned int i=0; i<openPolygonList.size(); i++)
            {
                if (openPolygonList[i].size() < 1) continue;
                
                {
                    gapCloserResult res = findPolygonGapCloser(openPolygonList[i][0], openPolygonList[i][openPolygonList[i].size()-1]);
                    if (res.len > 0 && res.len < bestResult.len)
                    {
                        bestA = i;
                        bestB = i;
                        bestResult = res;
                    }
                }

                for(unsigned int j=0; j<openPolygonList.size(); j++)
                {
                    if (openPolygonList[j].size() < 1 || i == j) continue;
                    
                    gapCloserResult res = findPolygonGapCloser(openPolygonList[i][0], openPolygonList[j][openPolygonList[j].size()-1]);
                    if (res.len > 0 && res.len < bestResult.len)
                    {
                        bestA = i;
                        bestB = j;
                        bestResult = res;
                    }
                }
            }
            
            if (bestResult.len < LLONG_MAX)
            {
                if (bestA == bestB)
                {
                    if (bestResult.pointIdxA == bestResult.pointIdxB)
                    {
                        polygonList.add(openPolygonList[bestA]);
                        openPolygonList[bestA].clear();
                    }
                    else if (bestResult.AtoB)
                    {
                        unsigned int n = polygonList.size();
                        polygonList.add(ClipperLib::Polygon());
                        for(unsigned int j = bestResult.pointIdxA; j != bestResult.pointIdxB; j = (j + 1) % polygonList[bestResult.polygonIdx].size())
                            polygonList[n].push_back(polygonList[bestResult.polygonIdx][j]);
                        for(unsigned int j = openPolygonList[bestA].size() - 1; int(j) >= 0; j--)
                            polygonList[n].push_back(openPolygonList[bestA][j]);
                        openPolygonList[bestA].clear();
                    }
                    else
                    {
                        unsigned int n = polygonList.size();
                        polygonList.add(openPolygonList[bestA]);
                        for(unsigned int j = bestResult.pointIdxB; j != bestResult.pointIdxA; j = (j + 1) % polygonList[bestResult.polygonIdx].size())
                            polygonList[n].push_back(polygonList[bestResult.polygonIdx][j]);
                        openPolygonList[bestA].clear();
                    }
                }
                else
                {
                    if (bestResult.pointIdxA == bestResult.pointIdxB)
                    {
                        for(unsigned int n=0; n<openPolygonList[bestA].size(); n++)
                            openPolygonList[bestB].push_back(openPolygonList[bestA][n]);
                        openPolygonList[bestA].clear();
                    }
                    else if (bestResult.AtoB)
                    {
                        ClipperLib::Polygon poly;
                        for(unsigned int n = bestResult.pointIdxA; n != bestResult.pointIdxB; n = (n + 1) % polygonList[bestResult.polygonIdx].size())
                            poly.push_back(polygonList[bestResult.polygonIdx][n]);
                        for(unsigned int n=poly.size()-1;int(n) >= 0; n--)
                            openPolygonList[bestB].push_back(poly[n]);
                        for(unsigned int n=0; n<openPolygonList[bestA].size(); n++)
                            openPolygonList[bestB].push_back(openPolygonList[bestA][n]);
                        openPolygonList[bestA].clear();
                    }
                    else
                    {
                        for(unsigned int n = bestResult.pointIdxB; n != bestResult.pointIdxA; n = (n + 1) % polygonList[bestResult.polygonIdx].size())
                            openPolygonList[bestB].push_back(polygonList[bestResult.polygonIdx][n]);
                        for(unsigned int n = openPolygonList[bestA].size() - 1; int(n) >= 0; n--)
                            openPolygonList[bestB].push_back(openPolygonList[bestA][n]);
                        openPolygonList[bestA].clear();
                    }
                }
            }
            else
            {
                break;
            }
        }
    }

    /*
    int q=0;
    for(unsigned int i=0;i<openPolygonList.size();i++)
    {
        if (openPolygonList[i].size() < 2) continue;
        if (!q) printf("***\n");
        printf("S: %f %f\n", float(openPolygonList[i][0].X), float(openPolygonList[i][0].Y));
        printf("E: %f %f\n", float(openPolygonList[i][openPolygonList[i].size()-1].X), float(openPolygonList[i][openPolygonList[i].size()-1].Y));
        q = 1;
    }
    */
    //if (q) exit(1);

    if (keepNoneClosed)
    {
        for(unsigned int n=0; n<openPolygonList.size(); n++)
        {
            if (openPolygonList[n].size() > 0)
                polygonList.add(openPolygonList[n]);
        }
    }
    //Clear the openPolygonList to save memory, the only reason to keep it after this is for debugging.
    //openPolygonList.clear();

    //Remove all the tiny polygons, or polygons that are not closed. As they do not contribute to the actual print.
    int snapDistance = 1000;
    for(unsigned int i=0;i<polygonList.size();i++)
    {
        int length = 0;
        
        for(unsigned int n=1; n<polygonList[i].size(); n++)
        {
            length += vSize(polygonList[i][n] - polygonList[i][n-1]);
            if (length > snapDistance)
                break;
        }
        if (length < snapDistance)
        {
            polygonList.remove(i);
            i--;
        }
    }

    //Finally optimize all the polygons. Every point removed saves time in the long run.
    optimizePolygons(polygonList);
}
コード例 #29
0
ファイル: comb.cpp プロジェクト: anil235476/CuraEngine
bool Comb::moveInside(Point* from, int distance)
{
    Point ret = *from;
    int64_t maxDist2 =  MM2INT(2.0) * MM2INT(2.0);
    int64_t bestDist2 = maxDist2;
    for(PolygonRef poly : boundary)
    {
        if (poly.size() < 2)
            continue;
        Point p0 = poly[poly.size()-2];
        Point p1 = poly.back();
        bool projected_p_beyond_prev_segment = dot(p1 - p0, *from - p0) > vSize2(p1 - p0);
        for(Point& p2 : poly)
        {   
            // X = A + Normal( B - A ) * ((( B - A ) dot ( P - A )) / VSize( A - B ));
            // X = P projected on AB
            Point& a = p1;
            Point& b = p2;
            Point& p = *from;
            Point ab = b - a;
            Point ap = p - a;
            int64_t ab_length = vSize(ab);
            int64_t ax_length = dot(ab, ap) / ab_length;
            if (ax_length < 0) // x is projected to before ab
            {
                if (projected_p_beyond_prev_segment)
                { //  case which looks like:   > .
                    projected_p_beyond_prev_segment = false;
                    Point& x = p1;
                    
                    int64_t dist2 = vSize2(x - p);
                    if (dist2 < bestDist2)
                    {
                        bestDist2 = dist2;
                        ret = x + normal(crossZ(normal(a, distance*4) + normal(p1 - p0, distance*4)), distance); // *4 to retain more precision for the eventual normalization
                    }
                }
                else
                {
                    projected_p_beyond_prev_segment = false;
                    p0 = p1;
                    p1 = p2;
                    continue;
                }
            }
            else if (ax_length > ab_length) // x is projected to beyond ab
            {
                projected_p_beyond_prev_segment = true;
                p0 = p1;
                p1 = p2;
                continue;
            }
            else 
            {
                projected_p_beyond_prev_segment = false;
                Point x = a + ab * ax_length / ab_length;
                
                int64_t dist2 = vSize2(x - *from);
                if (dist2 < bestDist2)
                {
                    bestDist2 = dist2;
                    ret = x + crossZ(normal(ab, distance));
                }
            }
            
            
            p0 = p1;
            p1 = p2;
        }
    }
    if (bestDist2 < maxDist2)
    {
        *from = ret;
        return true;
    }
    return false;
}
コード例 #30
0
ファイル: comb.cpp プロジェクト: 976717326/CuraEngine
bool Comb::calc(Point startPoint, Point endPoint, CombPaths& combPaths, bool startInside, bool endInside, int64_t max_comb_distance_ignored)
{
    if (shorterThen(endPoint - startPoint, max_comb_distance_ignored))
    {
        return true;
    }

    //Move start and end point inside the comb boundary
    unsigned int start_inside_poly = NO_INDEX;
    if (startInside) 
    {
        start_inside_poly = PolygonUtils::moveInside(boundary_inside, startPoint, offset_extra_start_end, max_moveInside_distance2);
        if (!boundary_inside.inside(start_inside_poly) || start_inside_poly == NO_INDEX)
        {
            if (start_inside_poly != NO_INDEX)
            { // if not yet inside because of overshoot, try again
                start_inside_poly = PolygonUtils::moveInside(boundary_inside, startPoint, offset_extra_start_end, max_moveInside_distance2);
            }
            if (start_inside_poly == NO_INDEX)    //If we fail to move the point inside the comb boundary we need to retract.
            {
                startInside = false;
            }
        }
    }
    unsigned int end_inside_poly = NO_INDEX;
    if (endInside)
    {
        end_inside_poly = PolygonUtils::moveInside(boundary_inside, endPoint, offset_extra_start_end, max_moveInside_distance2);
        if (!boundary_inside.inside(endPoint) || end_inside_poly == NO_INDEX)
        {
            if (end_inside_poly != NO_INDEX)
            { // if not yet inside because of overshoot, try again
                end_inside_poly = PolygonUtils::moveInside(boundary_inside, endPoint, offset_extra_start_end, max_moveInside_distance2);
            }
            if (end_inside_poly == NO_INDEX)    //If we fail to move the point inside the comb boundary we need to retract.
            {
                endInside = false;
            }
        }
    }

    
    unsigned int start_part_boundary_poly_idx;
    unsigned int end_part_boundary_poly_idx;
    unsigned int start_part_idx =   (start_inside_poly == NO_INDEX)?    NO_INDEX : partsView_inside.getPartContaining(start_inside_poly, &start_part_boundary_poly_idx);
    unsigned int end_part_idx =     (end_inside_poly == NO_INDEX)?      NO_INDEX : partsView_inside.getPartContaining(end_inside_poly, &end_part_boundary_poly_idx);
    
    if (startInside && endInside && start_part_idx == end_part_idx)
    { // normal combing within part
        PolygonsPart part = partsView_inside.assemblePart(start_part_idx);
        combPaths.emplace_back();
        LinePolygonsCrossings::comb(part, startPoint, endPoint, combPaths.back(), -offset_dist_to_get_from_on_the_polygon_to_outside, max_comb_distance_ignored);
        return true;
    }
    else 
    { // comb inside part to edge (if needed) >> move through air avoiding other parts >> comb inside end part upto the endpoint (if needed) 
        //  INSIDE  |          in_between            |            OUTSIDE     |              in_between         |     INSIDE
        //        ^crossing_1_in     ^crossing_1_mid  ^crossing_1_out        ^crossing_2_out    ^crossing_2_mid   ^crossing_2_in
        //
        // when startPoint is inside crossing_1_in is of interest
        // when it is in between inside and outside it is equal to crossing_1_mid
        Point crossing_1_in_or_mid; // the point inside the starting polygon if startPoint is inside or the startPoint itself if it is not inside
        Point crossing_1_out;
        Point crossing_2_in_or_mid; // the point inside the ending polygon if endPoint is inside or the endPoint itself if it is not inside
        Point crossing_2_out;
        
        { // find crossing over the in-between area between inside and outside
            if (startInside)
            {
                ClosestPolygonPoint crossing_1_in_cp = PolygonUtils::findClosest(endPoint, boundary_inside[start_part_boundary_poly_idx]);
                crossing_1_in_or_mid = PolygonUtils::moveInside(crossing_1_in_cp, offset_dist_to_get_from_on_the_polygon_to_outside); // in-case
            }
            else 
            {
                crossing_1_in_or_mid = startPoint; // mid-case
            }

            if (endInside)
            {
                ClosestPolygonPoint crossing_2_in_cp = PolygonUtils::findClosest(crossing_1_in_or_mid, boundary_inside[end_part_boundary_poly_idx]);
                crossing_2_in_or_mid = PolygonUtils::moveInside(crossing_2_in_cp, offset_dist_to_get_from_on_the_polygon_to_outside); // in-case
            }
            else 
            {
                crossing_2_in_or_mid = endPoint; // mid-case
            }
        }
        
        bool avoid_other_parts_now = avoid_other_parts;
        if (avoid_other_parts_now && vSize2(crossing_1_in_or_mid - crossing_2_in_or_mid) < offset_from_outlines_outside * offset_from_outlines_outside * 4)
        { // parts are next to eachother, i.e. the direct crossing will always be smaller than two crossings via outside
            avoid_other_parts_now = false;
        }
        
        if (avoid_other_parts_now)
        { // compute the crossing points when moving through air
            Polygons& outside = getBoundaryOutside(); // comb through all air, since generally the outside consists of a single part
            
            
            crossing_1_out = crossing_1_in_or_mid;
            if (startInside || outside.inside(crossing_1_in_or_mid, true)) // start in_between
            { // move outside
                ClosestPolygonPoint* crossing_1_out_cpp = PolygonUtils::findClose(crossing_1_in_or_mid, outside, getOutsideLocToLine());
                if (crossing_1_out_cpp)
                {
                    crossing_1_out = PolygonUtils::moveOutside(*crossing_1_out_cpp, offset_dist_to_get_from_on_the_polygon_to_outside);
                }
                else 
                {
                    PolygonUtils::moveOutside(outside, crossing_1_out, offset_dist_to_get_from_on_the_polygon_to_outside);
                }
            }
            int64_t in_out_dist2_1 = vSize2(crossing_1_out - crossing_1_in_or_mid); 
            if (startInside && in_out_dist2_1 > max_crossing_dist2) // moveInside moved too far
            { // if move is to far over in_between
                // find crossing closer by
                std::shared_ptr<std::pair<ClosestPolygonPoint, ClosestPolygonPoint>> best = findBestCrossing(boundary_inside[start_part_boundary_poly_idx], startPoint, endPoint);
                if (best)
                {
                    crossing_1_in_or_mid = PolygonUtils::moveInside(best->first, offset_dist_to_get_from_on_the_polygon_to_outside);
                    crossing_1_out = PolygonUtils::moveOutside(best->second, offset_dist_to_get_from_on_the_polygon_to_outside);
                }
            }


            crossing_2_out = crossing_2_in_or_mid;
            if (endInside || outside.inside(crossing_2_in_or_mid, true))
            { // move outside
                ClosestPolygonPoint* crossing_2_out_cpp = PolygonUtils::findClose(crossing_2_in_or_mid, outside, getOutsideLocToLine());
                if (crossing_2_out_cpp)
                {
                    crossing_2_out = PolygonUtils::moveOutside(*crossing_2_out_cpp, offset_dist_to_get_from_on_the_polygon_to_outside);
                }
                else 
                {
                    PolygonUtils::moveOutside(outside, crossing_2_out, offset_dist_to_get_from_on_the_polygon_to_outside);
                }
            }
            int64_t in_out_dist2_2 = vSize2(crossing_2_out - crossing_2_in_or_mid); 
            if (endInside && in_out_dist2_2 > max_crossing_dist2) // moveInside moved too far
            { // if move is to far over in_between
                // find crossing closer by
                std::shared_ptr<std::pair<ClosestPolygonPoint, ClosestPolygonPoint>> best = findBestCrossing(boundary_inside[end_part_boundary_poly_idx], endPoint, crossing_1_out);
                if (best)
                {
                    crossing_2_in_or_mid = PolygonUtils::moveInside(best->first, offset_dist_to_get_from_on_the_polygon_to_outside);
                    crossing_2_out = PolygonUtils::moveOutside(best->second, offset_dist_to_get_from_on_the_polygon_to_outside);
                }
            }
        }

        if (startInside)
        {
            // start to boundary
            PolygonsPart part_begin = partsView_inside.assemblePart(start_part_idx); // comb through the starting part only
            combPaths.emplace_back();
            LinePolygonsCrossings::comb(part_begin, startPoint, crossing_1_in_or_mid, combPaths.back(), -offset_dist_to_get_from_on_the_polygon_to_outside, max_comb_distance_ignored);
        }
        
        // throught air from boundary to boundary
        if (avoid_other_parts_now)
        {
            combPaths.emplace_back();
            combPaths.throughAir = true;
            if ( vSize(crossing_1_in_or_mid - crossing_2_in_or_mid) < vSize(crossing_1_in_or_mid - crossing_1_out) + vSize(crossing_2_in_or_mid - crossing_2_out) )
            { // via outside is moving more over the in-between zone
                combPaths.back().push_back(crossing_1_in_or_mid);
                combPaths.back().push_back(crossing_2_in_or_mid);
            }
            else
            {
                LinePolygonsCrossings::comb(getBoundaryOutside(), crossing_1_out, crossing_2_out, combPaths.back(), offset_dist_to_get_from_on_the_polygon_to_outside, max_comb_distance_ignored);
            }
        }
        else 
        { // directly through air (not avoiding other parts)
            combPaths.emplace_back();
            combPaths.throughAir = true;
            combPaths.back().cross_boundary = true; // TODO: calculate whether we cross a boundary!
            combPaths.back().push_back(crossing_1_in_or_mid);
            combPaths.back().push_back(crossing_2_in_or_mid);
        }
        
        if (endInside)
        {
            // boundary to end
            PolygonsPart part_end = partsView_inside.assemblePart(end_part_idx); // comb through end part only
            combPaths.emplace_back();
            LinePolygonsCrossings::comb(part_end, crossing_2_in_or_mid, endPoint, combPaths.back(), -offset_dist_to_get_from_on_the_polygon_to_outside, max_comb_distance_ignored);
        }
        
        return true;
    }
}