From a02d704d0a41fdc1157f93075042d4795b2649ea Mon Sep 17 00:00:00 2001 From: sliptonic Date: Thu, 9 Jun 2016 10:02:42 -0500 Subject: [PATCH] Updated libarea with changes from Heeks/libarea --- src/Mod/Path/libarea/Arc.cpp | 31 +- src/Mod/Path/libarea/Arc.h | 29 +- src/Mod/Path/libarea/Area.cpp | 34 +- src/Mod/Path/libarea/Area.h | 32 +- src/Mod/Path/libarea/AreaClipper.cpp | 107 +- src/Mod/Path/libarea/AreaDxf.cpp | 31 + src/Mod/Path/libarea/AreaDxf.h | 23 + src/Mod/Path/libarea/AreaPocket.cpp | 62 +- src/Mod/Path/libarea/CMakeLists.txt | 2 + src/Mod/Path/libarea/Curve.cpp | 44 +- src/Mod/Path/libarea/PythonStuff.cpp | 58 +- src/Mod/Path/libarea/PythonStuff.h | 28 +- src/Mod/Path/libarea/clipper.cpp | 16 +- src/Mod/Path/libarea/clipper.hpp | 4 +- src/Mod/Path/libarea/dxf.cpp | 1634 +++++++++++++++++++ src/Mod/Path/libarea/dxf.h | 158 ++ src/Mod/Path/libarea/kurve/Construction.cpp | 44 +- src/Mod/Path/libarea/kurve/Finite.cpp | 43 +- src/Mod/Path/libarea/kurve/Matrix.cpp | 34 +- src/Mod/Path/libarea/kurve/geometry.h | 49 +- src/Mod/Path/libarea/kurve/kurve.cpp | 77 +- src/Mod/Path/libarea/kurve/offset.cpp | 31 +- 22 files changed, 2028 insertions(+), 543 deletions(-) create mode 100644 src/Mod/Path/libarea/AreaDxf.cpp create mode 100644 src/Mod/Path/libarea/AreaDxf.h create mode 100644 src/Mod/Path/libarea/dxf.cpp create mode 100644 src/Mod/Path/libarea/dxf.h diff --git a/src/Mod/Path/libarea/Arc.cpp b/src/Mod/Path/libarea/Arc.cpp index cf76557ee..d1e0498ca 100644 --- a/src/Mod/Path/libarea/Arc.cpp +++ b/src/Mod/Path/libarea/Arc.cpp @@ -1,32 +1,7 @@ // Arc.cpp -/*============================== -Copyright (c) 2011-2015 Dan Heeks - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -==============================*/ - - +// Copyright 2011, Dan Heeks +// This program is released under the BSD license. See the file COPYING for details. #include "Arc.h" #include "Curve.h" @@ -91,7 +66,7 @@ Point CArc::MidParam(double param)const { //segments - number of segments per full revolution! //d_angle - determines the direction and the ammount of the arc to draw -void CArc::GetSegments(void(*callbackfunc)(const double *p), double pixels_per_mm, bool want_start_point)const +void CArc::GetSegments(void(*callbackfunc)(const double *p), double pixels_per_mm)const { if(m_s == m_e) return; diff --git a/src/Mod/Path/libarea/Arc.h b/src/Mod/Path/libarea/Arc.h index 9455a8470..66450e12d 100644 --- a/src/Mod/Path/libarea/Arc.h +++ b/src/Mod/Path/libarea/Arc.h @@ -1,29 +1,6 @@ // Arc.h -/*============================== -Copyright (c) 2011-2015 Dan Heeks - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -==============================*/ +// Copyright 2011, Dan Heeks +// This program is released under the BSD license. See the file COPYING for details. #pragma once @@ -44,5 +21,5 @@ public: double IncludedAngle()const; // always > 0 bool AlmostALine()const; Point MidParam(double param)const; - void GetSegments(void(*callbackfunc)(const double *p), double pixels_per_mm, bool want_start_point = true)const; + void GetSegments(void(*callbackfunc)(const double *p), double pixels_per_mm)const; }; \ No newline at end of file diff --git a/src/Mod/Path/libarea/Area.cpp b/src/Mod/Path/libarea/Area.cpp index c0d1e9285..f33e338c0 100644 --- a/src/Mod/Path/libarea/Area.cpp +++ b/src/Mod/Path/libarea/Area.cpp @@ -1,31 +1,7 @@ // Area.cpp -/*============================== -Copyright (c) 2011-2015 Dan Heeks - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -==============================*/ - +// Copyright 2011, Dan Heeks +// This program is released under the BSD license. See the file COPYING for details. #include "Area.h" #include "AreaOrderer.h" @@ -219,13 +195,13 @@ static void make_zig_curve(const CCurve& input_curve, double y0, double y) // find a high point to start looking from Point top_left; - int top_left_index; + int top_left_index = 0; bool top_left_found = false; Point top_right; - int top_right_index; + int top_right_index = 0; bool top_right_found = false; Point bottom_left; - int bottom_left_index; + int bottom_left_index = 0; bool bottom_left_found = false; int i =0; diff --git a/src/Mod/Path/libarea/Area.h b/src/Mod/Path/libarea/Area.h index 5895613d2..add4dcdc1 100644 --- a/src/Mod/Path/libarea/Area.h +++ b/src/Mod/Path/libarea/Area.h @@ -1,30 +1,7 @@ // Area.h -/*============================== -Copyright (c) 2011-2015 Dan Heeks - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -==============================*/ - +// Copyright 2011, Dan Heeks +// This program is released under the BSD license. See the file COPYING for details. +// repository now moved to github #ifndef AREA_HEADER #define AREA_HEADER @@ -78,11 +55,12 @@ public: void Subtract(const CArea& a2); void Intersect(const CArea& a2); void Union(const CArea& a2); + static CArea UniteCurves(std::list &curves); void Xor(const CArea& a2); void Offset(double inwards_value); void Thicken(double value); void FitArcs(); - unsigned int num_curves(){return static_cast(m_curves.size());} + unsigned int num_curves(){return m_curves.size();} Point NearestPoint(const Point& p)const; void GetBox(CBox2D &box); void Reorder(); diff --git a/src/Mod/Path/libarea/AreaClipper.cpp b/src/Mod/Path/libarea/AreaClipper.cpp index bcb6e26ef..608707835 100644 --- a/src/Mod/Path/libarea/AreaClipper.cpp +++ b/src/Mod/Path/libarea/AreaClipper.cpp @@ -1,32 +1,7 @@ // AreaClipper.cpp + // implements CArea methods using Angus Johnson's "Clipper" -/*============================== -Copyright (c) 2011-2015 Dan Heeks - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -==============================*/ - #include "Area.h" #include "clipper.hpp" using namespace ClipperLib; @@ -134,34 +109,6 @@ static void AddVertex(const CVertex& vertex, const CVertex* prev_vertex) } } -#if 0 -static bool IsPolygonClockwise(const TPolygon& p) -{ -#if 1 - double area = 0.0; - std::size_t s = p.size(); - for(std::size_t i = 0; i 0.0; -#else - return IsClockwise(p); -#endif -} -#endif - - static void MakeLoop(const DoubleAreaPoint &pt0, const DoubleAreaPoint &pt1, const DoubleAreaPoint &pt2, double radius) { Point p0(pt0.X, pt0.Y); @@ -222,7 +169,7 @@ static void OffsetWithLoops(const TPolyPolygon &pp, TPolyPolygon &pp_new, double { if(reverse) { - for(std::size_t j = p.size()-1; j > 1; j--)MakeLoop(p[j], p[j-1], p[j-2], radius); + for(unsigned int j = p.size()-1; j > 1; j--)MakeLoop(p[j], p[j-1], p[j-2], radius); MakeLoop(p[1], p[0], p[p.size()-1], radius); MakeLoop(p[0], p[p.size()-1], p[p.size()-2], radius); } @@ -266,7 +213,7 @@ static void OffsetWithLoops(const TPolyPolygon &pp, TPolyPolygon &pp_new, double const TPolygon& p = copy[i]; TPolygon p_new; p_new.resize(p.size()); - std::size_t size_minus_one = p.size() - 1; + int size_minus_one = p.size() - 1; for(unsigned int j = 0; j < p.size(); j++)p_new[j] = p[size_minus_one - j]; pp_new[i] = p_new; } @@ -343,7 +290,7 @@ static void OffsetSpansWithObrounds(const CArea& area, TPolyPolygon &pp_new, dou const TPolygon& p = copy[i]; TPolygon p_new; p_new.resize(p.size()); - std::size_t size_minus_one = p.size() - 1; + int size_minus_one = p.size() - 1; for(unsigned int j = 0; j < p.size(); j++)p_new[j] = p[size_minus_one - j]; pp_new[i] = p_new; } @@ -368,7 +315,7 @@ static void MakePolyPoly( const CArea& area, TPolyPolygon &pp, bool reverse = tr p.resize(pts_for_AddVertex.size()); if(reverse) { - std::size_t i = pts_for_AddVertex.size() - 1;// clipper wants them the opposite way to CArea + unsigned int i = pts_for_AddVertex.size() - 1;// clipper wants them the opposite way to CArea for(std::list::iterator It = pts_for_AddVertex.begin(); It != pts_for_AddVertex.end(); It++, i--) { p[i] = It->int_point(); @@ -387,6 +334,27 @@ static void MakePolyPoly( const CArea& area, TPolyPolygon &pp, bool reverse = tr } } +static void MakePoly(const CCurve& curve, TPolygon &p) +{ + pts_for_AddVertex.clear(); + const CVertex* prev_vertex = NULL; + for (std::list::const_iterator It2 = curve.m_vertices.begin(); It2 != curve.m_vertices.end(); It2++) + { + const CVertex& vertex = *It2; + if (prev_vertex)AddVertex(vertex, prev_vertex); + prev_vertex = &vertex; + } + + p.resize(pts_for_AddVertex.size()); + { + unsigned int i = 0; + for (std::list::iterator It = pts_for_AddVertex.begin(); It != pts_for_AddVertex.end(); It++, i++) + { + p[i] = It->int_point(); + } + } +} + static void SetFromResult( CCurve& curve, const TPolygon& p, bool reverse = true ) { for(unsigned int j = 0; j < p.size(); j++) @@ -458,6 +426,29 @@ void CArea::Union(const CArea& a2) SetFromResult(*this, solution); } +// static +CArea CArea::UniteCurves(std::list &curves) +{ + Clipper c; + + TPolyPolygon pp; + + for (std::list::iterator It = curves.begin(); It != curves.end(); It++) + { + CCurve &curve = *It; + TPolygon p; + MakePoly(curve, p); + pp.push_back(p); + } + + c.AddPaths(pp, ptSubject, true); + TPolyPolygon solution; + c.Execute(ctUnion, solution, pftNonZero, pftNonZero); + CArea area; + SetFromResult(area, solution); + return area; +} + void CArea::Xor(const CArea& a2) { Clipper c; diff --git a/src/Mod/Path/libarea/AreaDxf.cpp b/src/Mod/Path/libarea/AreaDxf.cpp new file mode 100644 index 000000000..fa6293d24 --- /dev/null +++ b/src/Mod/Path/libarea/AreaDxf.cpp @@ -0,0 +1,31 @@ +// AreaDxf.cpp +// Copyright (c) 2011, Dan Heeks +// This program is released under the BSD license. See the file COPYING for details. + +#include "AreaDxf.h" +#include "Area.h" + +AreaDxfRead::AreaDxfRead(CArea* area, const char* filepath):CDxfRead(filepath), m_area(area){} + +void AreaDxfRead::StartCurveIfNecessary(const double* s) +{ + Point ps(s); + if((m_area->m_curves.size() == 0) || (m_area->m_curves.back().m_vertices.size() == 0) || (m_area->m_curves.back().m_vertices.back().m_p != ps)) + { + // start a new curve + m_area->m_curves.push_back(CCurve()); + m_area->m_curves.back().m_vertices.push_back(ps); + } +} + +void AreaDxfRead::OnReadLine(const double* s, const double* e) +{ + StartCurveIfNecessary(s); + m_area->m_curves.back().m_vertices.push_back(Point(e)); +} + +void AreaDxfRead::OnReadArc(const double* s, const double* e, const double* c, bool dir) +{ + StartCurveIfNecessary(s); + m_area->m_curves.back().m_vertices.push_back(CVertex(dir?1:0, Point(e), Point(c))); +} diff --git a/src/Mod/Path/libarea/AreaDxf.h b/src/Mod/Path/libarea/AreaDxf.h new file mode 100644 index 000000000..066ff8356 --- /dev/null +++ b/src/Mod/Path/libarea/AreaDxf.h @@ -0,0 +1,23 @@ +// AreaDxf.h +// Copyright (c) 2011, Dan Heeks +// This program is released under the BSD license. See the file COPYING for details. + +#pragma once + +#include "dxf.h" + +class CSketch; +class CArea; +class CCurve; + +class AreaDxfRead : public CDxfRead{ + void StartCurveIfNecessary(const double* s); + +public: + CArea* m_area; + AreaDxfRead(CArea* area, const char* filepath); + + // AreaDxfRead's virtual functions + void OnReadLine(const double* s, const double* e); + void OnReadArc(const double* s, const double* e, const double* c, bool dir); +}; diff --git a/src/Mod/Path/libarea/AreaPocket.cpp b/src/Mod/Path/libarea/AreaPocket.cpp index 0c6c69d13..4e177a7f7 100644 --- a/src/Mod/Path/libarea/AreaPocket.cpp +++ b/src/Mod/Path/libarea/AreaPocket.cpp @@ -1,33 +1,9 @@ // AreaPocket.cpp +// Copyright 2011, Dan Heeks +// This program is released under the BSD license. See the file COPYING for details. + // implements CArea::MakeOnePocketCurve -/*============================== -Copyright (c) 2011-2015 Dan Heeks - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -==============================*/ - - #include "Area.h" #include @@ -425,38 +401,6 @@ void recur(std::list &arealist, const CArea& a1, const CAreaPocketParams } } -#if 0 -static CArea make_obround(const Point& p0, const Point& p1, double radius) -{ - Point dir = p1 - p0; - dir.normalize(); - Point right(dir.y, -dir.x); - CArea obround; - CCurve c; - if(fabs(radius) < 0.0000001)radius = (radius > 0.0) ? 0.002 : (-0.002); - Point vt0 = p0 + right * radius; - Point vt1 = p1 + right * radius; - Point vt2 = p1 - right * radius; - Point vt3 = p0 - right * radius; - c.append(vt0); - c.append(vt1); - c.append(CVertex(1, vt2, p1)); - c.append(vt3); - c.append(CVertex(1, vt0, p0)); - obround.append(c); - return obround; -} -#endif - -#if 0 -static bool feed_possible(const CArea &area_for_feed_possible, const Point& p0, const Point& p1, double tool_radius) -{ - CArea obround = make_obround(p0, p1, tool_radius); - obround.Subtract(area_for_feed_possible); - return obround.m_curves.empty(); -} -#endif - void MarkOverlappingOffsetIslands(std::list &offset_islands) { for(std::list::iterator It1 = offset_islands.begin(); It1 != offset_islands.end(); It1++) diff --git a/src/Mod/Path/libarea/CMakeLists.txt b/src/Mod/Path/libarea/CMakeLists.txt index b2d15d81d..f1b7807f9 100644 --- a/src/Mod/Path/libarea/CMakeLists.txt +++ b/src/Mod/Path/libarea/CMakeLists.txt @@ -25,10 +25,12 @@ endif() set(AREA_SRC_COMMON Arc.cpp Area.cpp + AreaDxf.cpp AreaOrderer.cpp AreaPocket.cpp Circle.cpp Curve.cpp + dxf.cpp kurve/Construction.cpp kurve/Finite.cpp kurve/kurve.cpp diff --git a/src/Mod/Path/libarea/Curve.cpp b/src/Mod/Path/libarea/Curve.cpp index f0618211e..707272520 100644 --- a/src/Mod/Path/libarea/Curve.cpp +++ b/src/Mod/Path/libarea/Curve.cpp @@ -1,30 +1,6 @@ // Curve.cpp - -/*============================== -Copyright (c) 2011-2015 Dan Heeks - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -==============================*/ +// Copyright 2011, Dan Heeks +// This program is released under the BSD license. See the file COPYING for details. #include "Curve.h" #include "Circle.h" @@ -86,7 +62,7 @@ bool CCurve::CheckForArc(const CVertex& prev_vt, std::list& migh if(might_be_an_arc.size() < 2)return false; // find middle point - int num = static_cast(might_be_an_arc.size()); + int num = might_be_an_arc.size(); int i = 0; const CVertex* mid_vt = NULL; int mid_i = (num-1)/2; @@ -217,7 +193,13 @@ void CCurve::FitArcs() { CVertex& vt = *It; if(vt.m_type || i == 0) + { + if (i != 0) + { + AddArcOrLines(false, new_vertices, might_be_an_arc, arc, arc_found, arc_added); + } new_vertices.push_back(vt); + } else { might_be_an_arc.push_back(&vt); @@ -720,13 +702,6 @@ static geoff_geometry::Span MakeSpan(const Span& span) return geoff_geometry::Span(span.m_v.m_type, geoff_geometry::Point(span.m_p.x, span.m_p.y), geoff_geometry::Point(span.m_v.m_p.x, span.m_v.m_p.y), geoff_geometry::Point(span.m_v.m_c.x, span.m_v.m_c.y)); } -#if 0 -static Span MakeCSpan(const geoff_geometry::Span &sp) -{ - return Span(Point(sp.p0.x, sp.p0.y), CVertex(sp.dir, Point(sp.p1.x, sp.p1.y), Point(sp.pc.x, sp.pc.y))); -} -#endif - bool CCurve::Offset(double leftwards_value) { // use the kurve code donated by Geoff Hawkesford, to offset the curve as an open curve @@ -913,6 +888,7 @@ double CCurve::PointToPerim(const Point& p)const { double best_dist = 0.0; double perim_at_best_dist = 0.0; + Point best_point = Point(0, 0); bool best_dist_found = false; double perim = 0.0; diff --git a/src/Mod/Path/libarea/PythonStuff.cpp b/src/Mod/Path/libarea/PythonStuff.cpp index 9029dc6e1..7f48114b3 100644 --- a/src/Mod/Path/libarea/PythonStuff.cpp +++ b/src/Mod/Path/libarea/PythonStuff.cpp @@ -1,45 +1,14 @@ // PythonStuff.cpp - -/*============================== -Copyright (c) 2011-2015 Dan Heeks - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -==============================*/ - +// Copyright 2011, Dan Heeks +// This program is released under the BSD license. See the file COPYING for details. #include "PythonStuff.h" #include "Area.h" #include "Point.h" +#include "AreaDxf.h" #include "kurve/geometry.h" -#if defined (_POSIX_C_SOURCE) -# undef _POSIX_C_SOURCE -#endif -#if defined (_XOPEN_SOURCE) -# undef _XOPEN_SOURCE -#endif - #if _DEBUG #undef _DEBUG #include @@ -51,9 +20,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifdef __GNUG__ #pragma implementation #endif -#ifdef _MSC_VER -#pragma warning(disable : 4244) -#endif #include #include @@ -96,8 +62,8 @@ boost::python::tuple transformed_point(const geoff_geometry::Matrix &matrix, dou static void print_curve(const CCurve& c) { - std::size_t nvertices = c.m_vertices.size(); - printf("number of vertices = %lu\n", nvertices); + unsigned int nvertices = c.m_vertices.size(); + printf("number of vertices = %d\n", nvertices); int i = 0; for(std::list::const_iterator It = c.m_vertices.begin(); It != c.m_vertices.end(); It++, i++) { @@ -119,7 +85,7 @@ static void print_area(const CArea &a) static unsigned int num_vertices(const CCurve& curve) { - return static_cast(curve.m_vertices.size()); + return curve.m_vertices.size(); } static CVertex FirstVertex(const CCurve& curve) @@ -147,6 +113,13 @@ static bool holes_linked() return CArea::HolesLinked(); } +static CArea AreaFromDxf(const char* filepath) +{ + CArea area; + AreaDxfRead dxf(&area, filepath); + dxf.DoRead(); + return area; +} static void append_point(CCurve& c, const Point& p) { @@ -187,6 +160,10 @@ boost::python::list SplitArea(const CArea& a) return alist; } +void dxfArea(CArea& area, const char* str) +{ + area = CArea(); +} boost::python::list getCurveSpans(const CCurve& c) { @@ -427,5 +404,6 @@ BOOST_PYTHON_MODULE(area) { bp::def("set_units", set_units); bp::def("get_units", get_units); bp::def("holes_linked", holes_linked); + bp::def("AreaFromDxf", AreaFromDxf); bp::def("TangentialArc", TangentialArc); } diff --git a/src/Mod/Path/libarea/PythonStuff.h b/src/Mod/Path/libarea/PythonStuff.h index f767f16bc..7bc23d47e 100644 --- a/src/Mod/Path/libarea/PythonStuff.h +++ b/src/Mod/Path/libarea/PythonStuff.h @@ -1,31 +1,7 @@ // PythonStuff.h -/*============================== -Copyright (c) 2011-2015 Dan Heeks - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -==============================*/ - +// Copyright 2011, Dan Heeks +// This program is released under the BSD license. See the file COPYING for details. extern void Message(const char*); diff --git a/src/Mod/Path/libarea/clipper.cpp b/src/Mod/Path/libarea/clipper.cpp index d6bb0827a..bb0bfebc9 100644 --- a/src/Mod/Path/libarea/clipper.cpp +++ b/src/Mod/Path/libarea/clipper.cpp @@ -1440,7 +1440,7 @@ bool Clipper::ExecuteInternal() ProcessHorizontals(false); if (m_Scanbeam.empty()) break; cInt topY = PopScanbeam(); - succeeded = ProcessIntersections(botY, topY); + succeeded = ProcessIntersections(topY); if (!succeeded) break; ProcessEdgesAtTopOfScanbeam(topY); botY = topY; @@ -2705,11 +2705,11 @@ void Clipper::UpdateEdgeIntoAEL(TEdge *&e) } //------------------------------------------------------------------------------ -bool Clipper::ProcessIntersections(const cInt botY, const cInt topY) +bool Clipper::ProcessIntersections(const cInt topY) { if( !m_ActiveEdges ) return true; try { - BuildIntersectList(botY, topY); + BuildIntersectList(topY); size_t IlSize = m_IntersectList.size(); if (IlSize == 0) return true; if (IlSize == 1 || FixupIntersectionOrder()) ProcessIntersectList(); @@ -2734,7 +2734,7 @@ void Clipper::DisposeIntersectNodes() } //------------------------------------------------------------------------------ -void Clipper::BuildIntersectList(const cInt botY, const cInt topY) +void Clipper::BuildIntersectList(const cInt topY) { if ( !m_ActiveEdges ) return; @@ -4161,10 +4161,10 @@ double DistanceFromLineSqrd( const IntPoint& pt, const IntPoint& ln1, const IntPoint& ln2) { //The equation of a line in general form (Ax + By + C = 0) - //given 2 points (x¹,y¹) & (x²,y²) is ... - //(y¹ - y²)x + (x² - x¹)y + (y² - y¹)x¹ - (x² - x¹)y¹ = 0 - //A = (y¹ - y²); B = (x² - x¹); C = (y² - y¹)x¹ - (x² - x¹)y¹ - //perpendicular distance of point (x³,y³) = (Ax³ + By³ + C)/Sqrt(A² + B²) + //given 2 points (x¹,y¹) & (x²,y²) is ... + //(y¹ - y²)x + (x² - x¹)y + (y² - y¹)x¹ - (x² - x¹)y¹ = 0 + //A = (y¹ - y²); B = (x² - x¹); C = (y² - y¹)x¹ - (x² - x¹)y¹ + //perpendicular distance of point (x³,y³) = (Ax³ + By³ + C)/Sqrt(A² + B²) //see http://en.wikipedia.org/wiki/Perpendicular_distance double A = double(ln1.Y - ln2.Y); double B = double(ln2.X - ln1.X); diff --git a/src/Mod/Path/libarea/clipper.hpp b/src/Mod/Path/libarea/clipper.hpp index e83e70a95..15af31e46 100644 --- a/src/Mod/Path/libarea/clipper.hpp +++ b/src/Mod/Path/libarea/clipper.hpp @@ -318,8 +318,8 @@ private: OutPt* AddOutPt(TEdge *e, const IntPoint &pt); void DisposeAllOutRecs(); void DisposeOutRec(PolyOutList::size_type index); - bool ProcessIntersections(const cInt botY, const cInt topY); - void BuildIntersectList(const cInt botY, const cInt topY); + bool ProcessIntersections(const cInt topY); + void BuildIntersectList(const cInt topY); void ProcessIntersectList(); void ProcessEdgesAtTopOfScanbeam(const cInt topY); void BuildResult(Paths& polys); diff --git a/src/Mod/Path/libarea/dxf.cpp b/src/Mod/Path/libarea/dxf.cpp new file mode 100644 index 000000000..4795281d4 --- /dev/null +++ b/src/Mod/Path/libarea/dxf.cpp @@ -0,0 +1,1634 @@ +// dxf.cpp +// Copyright 2011, Dan Heeks +// This program is released under the BSD license. See the file COPYING for details. + +#include "dxf.h" + +using namespace std; +static const double Pi = 3.14159265358979323846264338327950288419716939937511; + +CDxfWrite::CDxfWrite(const char* filepath) +{ + // start the file + m_fail = false; +#ifdef __WXMSW__ + m_ofs = new ofstream(filepath, ios::out); +#else + m_ofs = new ofstream(filepath, ios::out); +#endif + if(!(*m_ofs)){ + m_fail = true; + return; + } + m_ofs->imbue(std::locale("C")); + + // start + (*m_ofs) << 0 << endl; + (*m_ofs) << "SECTION" << endl; + (*m_ofs) << 2 << endl; + (*m_ofs) << "ENTITIES" << endl; +} + +CDxfWrite::~CDxfWrite() +{ + // end + (*m_ofs) << 0 << endl; + (*m_ofs) << "ENDSEC" << endl; + (*m_ofs) << 0 << endl; + (*m_ofs) << "EOF"; + + delete m_ofs; +} + +void CDxfWrite::WriteLine(const double* s, const double* e, const char* layer_name) +{ + (*m_ofs) << 0 << endl; + (*m_ofs) << "LINE" << endl; + (*m_ofs) << 8 << endl; // Group code for layer name + (*m_ofs) << layer_name << endl; // Layer number + (*m_ofs) << 10 << endl; // Start point of line + (*m_ofs) << s[0] << endl; // X in WCS coordinates + (*m_ofs) << 20 << endl; + (*m_ofs) << s[1] << endl; // Y in WCS coordinates + (*m_ofs) << 30 << endl; + (*m_ofs) << s[2] << endl; // Z in WCS coordinates + (*m_ofs) << 11 << endl; // End point of line + (*m_ofs) << e[0] << endl; // X in WCS coordinates + (*m_ofs) << 21 << endl; + (*m_ofs) << e[1] << endl; // Y in WCS coordinates + (*m_ofs) << 31 << endl; + (*m_ofs) << e[2] << endl; // Z in WCS coordinates +} + +void CDxfWrite::WritePoint(const double* s, const char* layer_name) +{ + (*m_ofs) << 0 << endl; + (*m_ofs) << "POINT" << endl; + (*m_ofs) << 8 << endl; // Group code for layer name + (*m_ofs) << layer_name << endl; // Layer number + (*m_ofs) << 10 << endl; // Start point of line + (*m_ofs) << s[0] << endl; // X in WCS coordinates + (*m_ofs) << 20 << endl; + (*m_ofs) << s[1] << endl; // Y in WCS coordinates + (*m_ofs) << 30 << endl; + (*m_ofs) << s[2] << endl; // Z in WCS coordinates +} + +void CDxfWrite::WriteArc(const double* s, const double* e, const double* c, bool dir, const char* layer_name) +{ + double ax = s[0] - c[0]; + double ay = s[1] - c[1]; + double bx = e[0] - c[0]; + double by = e[1] - c[1]; + + double start_angle = atan2(ay, ax) * 180/Pi; + double end_angle = atan2(by, bx) * 180/Pi; + double radius = sqrt(ax*ax + ay*ay); + if(!dir){ + double temp = start_angle; + start_angle = end_angle; + end_angle = temp; + } + (*m_ofs) << 0 << endl; + (*m_ofs) << "ARC" << endl; + (*m_ofs) << 8 << endl; // Group code for layer name + (*m_ofs) << layer_name << endl; // Layer number + (*m_ofs) << 10 << endl; // Centre X + (*m_ofs) << c[0] << endl; // X in WCS coordinates + (*m_ofs) << 20 << endl; + (*m_ofs) << c[1] << endl; // Y in WCS coordinates + (*m_ofs) << 30 << endl; + (*m_ofs) << c[2] << endl; // Z in WCS coordinates + (*m_ofs) << 40 << endl; // + (*m_ofs) << radius << endl; // Radius + (*m_ofs) << 50 << endl; + (*m_ofs) << start_angle << endl; // Start angle + (*m_ofs) << 51 << endl; + (*m_ofs) << end_angle << endl; // End angle +} + +void CDxfWrite::WriteCircle(const double* c, double radius, const char* layer_name) +{ + (*m_ofs) << 0 << endl; + (*m_ofs) << "CIRCLE" << endl; + (*m_ofs) << 8 << endl; // Group code for layer name + (*m_ofs) << layer_name << endl; // Layer number + (*m_ofs) << 10 << endl; // Centre X + (*m_ofs) << c[0] << endl; // X in WCS coordinates + (*m_ofs) << 20 << endl; + (*m_ofs) << c[1] << endl; // Y in WCS coordinates + (*m_ofs) << 30 << endl; + (*m_ofs) << c[2] << endl; // Z in WCS coordinates + (*m_ofs) << 40 << endl; // + (*m_ofs) << radius << endl; // Radius +} + +void CDxfWrite::WriteEllipse(const double* c, double major_radius, double minor_radius, double rotation, double start_angle, double end_angle, bool dir, const char* layer_name ) +{ + double m[3]; + m[2]=0; + m[0] = major_radius * sin(rotation); + m[1] = major_radius * cos(rotation); + + double ratio = minor_radius/major_radius; + + if(!dir){ + double temp = start_angle; + start_angle = end_angle; + end_angle = temp; + } + (*m_ofs) << 0 << endl; + (*m_ofs) << "ELLIPSE" << endl; + (*m_ofs) << 8 << endl; // Group code for layer name + (*m_ofs) << layer_name << endl; // Layer number + (*m_ofs) << 10 << endl; // Centre X + (*m_ofs) << c[0] << endl; // X in WCS coordinates + (*m_ofs) << 20 << endl; + (*m_ofs) << c[1] << endl; // Y in WCS coordinates + (*m_ofs) << 30 << endl; + (*m_ofs) << c[2] << endl; // Z in WCS coordinates + (*m_ofs) << 40 << endl; // + (*m_ofs) << ratio << endl; // Ratio + (*m_ofs) << 11 << endl; // + (*m_ofs) << m[0] << endl; // Major X + (*m_ofs) << 21 << endl; + (*m_ofs) << m[1] << endl; // Major Y + (*m_ofs) << 31 << endl; + (*m_ofs) << m[2] << endl; // Major Z + (*m_ofs) << 41 << endl; + (*m_ofs) << start_angle << endl; // Start angle + (*m_ofs) << 42 << endl; + (*m_ofs) << end_angle << endl; // End angle +} + +CDxfRead::CDxfRead(const char* filepath) +{ + // start the file + memset( m_unused_line, '\0', sizeof(m_unused_line) ); + m_fail = false; + m_eUnits = eMillimeters; + strcpy(m_layer_name, "0"); // Default layer name + m_ignore_errors = true; + + m_ifs = new ifstream(filepath); + if(!(*m_ifs)){ + m_fail = true; + return; + } + m_ifs->imbue(std::locale("C")); + +} + +CDxfRead::~CDxfRead() +{ + delete m_ifs; +} + +double CDxfRead::mm( const double & value ) const +{ + switch(m_eUnits) + { + case eUnspecified: return(value * 1.0); // We don't know any better. + case eInches: return(value * 25.4); + case eFeet: return(value * 25.4 * 12); + case eMiles: return(value * 1609344.0); + case eMillimeters: return(value * 1.0); + case eCentimeters: return(value * 10.0); + case eMeters: return(value * 1000.0); + case eKilometers: return(value * 1000000.0); + case eMicroinches: return(value * 25.4 / 1000.0); + case eMils: return(value * 25.4 / 1000.0); + case eYards: return(value * 3 * 12 * 25.4); + case eAngstroms: return(value * 0.0000001); + case eNanometers: return(value * 0.000001); + case eMicrons: return(value * 0.001); + case eDecimeters: return(value * 100.0); + case eDekameters: return(value * 10000.0); + case eHectometers: return(value * 100000.0); + case eGigameters: return(value * 1000000000000.0); + case eAstronomicalUnits: return(value * 149597870690000.0); + case eLightYears: return(value * 9454254955500000000.0); + case eParsecs: return(value * 30856774879000000000.0); + default: return(value * 1.0); // We don't know any better. + } // End switch +} // End mm() method + + +bool CDxfRead::ReadLine() +{ + double s[3] = {0, 0, 0}; + double e[3] = {0, 0, 0}; + + while(!((*m_ifs).eof())) + { + get_line(); + int n; + + if(sscanf(m_str, "%d", &n) != 1) + { + printf("CDxfRead::ReadLine() Failed to read integer from '%s'\n", m_str ); + return false; + } + + std::istringstream ss; + ss.imbue(std::locale("C")); + switch(n){ + case 0: + // next item found, so finish with line + DerefACI(); + OnReadLine(s, e); + return true; + + case 8: // Layer name follows + get_line(); + strcpy(m_layer_name, m_str); + break; + + case 10: + // start x + get_line(); + ss.str(m_str); ss >> s[0]; s[0] = mm(s[0]); if(ss.fail()) return false; + break; + case 20: + // start y + get_line(); + ss.str(m_str); ss >> s[1]; s[1] = mm(s[1]); if(ss.fail()) return false; + break; + case 30: + // start z + get_line(); + ss.str(m_str); ss >> s[2]; s[2] = mm(s[2]); if(ss.fail()) return false; + break; + case 11: + // end x + get_line(); + ss.str(m_str); ss >> e[0]; e[0] = mm(e[0]); if(ss.fail()) return false; + break; + case 21: + // end y + get_line(); + ss.str(m_str); ss >> e[1]; e[1] = mm(e[1]); if(ss.fail()) return false; + break; + case 31: + // end z + get_line(); + ss.str(m_str); ss >> e[2]; e[2] = mm(e[2]); if(ss.fail()) return false; + break; + case 62: + // color index + get_line(); + ss.str(m_str); ss >> m_aci; if(ss.fail()) return false; + break; + + case 100: + case 39: + case 210: + case 220: + case 230: + // skip the next line + get_line(); + break; + default: + // skip the next line + get_line(); + break; + } + } + + try { + DerefACI(); + OnReadLine(s, e); + } + catch(...) + { + if (! IgnoreErrors()) throw; // Re-throw the exception. + } + + return false; +} + +bool CDxfRead::ReadPoint() +{ + double s[3] = {0, 0, 0}; + + while(!((*m_ifs).eof())) + { + get_line(); + int n; + + if(sscanf(m_str, "%d", &n) != 1) + { + printf("CDxfRead::ReadPoint() Failed to read integer from '%s'\n", m_str ); + return false; + } + + std::istringstream ss; + ss.imbue(std::locale("C")); + switch(n){ + case 0: + // next item found, so finish with line + DerefACI(); + OnReadPoint(s); + return true; + + case 8: // Layer name follows + get_line(); + strcpy(m_layer_name, m_str); + break; + + case 10: + // start x + get_line(); + ss.str(m_str); ss >> s[0]; s[0] = mm(s[0]); if(ss.fail()) return false; + break; + case 20: + // start y + get_line(); + ss.str(m_str); ss >> s[1]; s[1] = mm(s[1]); if(ss.fail()) return false; + break; + case 30: + // start z + get_line(); + ss.str(m_str); ss >> s[2]; s[2] = mm(s[2]); if(ss.fail()) return false; + break; + + case 62: + // color index + get_line(); + ss.str(m_str); ss >> m_aci; if(ss.fail()) return false; + break; + + case 100: + case 39: + case 210: + case 220: + case 230: + // skip the next line + get_line(); + break; + default: + // skip the next line + get_line(); + break; + } + + } + + try { + DerefACI(); + OnReadPoint(s); + } + catch(...) + { + if (! IgnoreErrors()) throw; // Re-throw the exception. + } + + return false; +} + +bool CDxfRead::ReadArc() +{ + double start_angle = 0.0;// in degrees + double end_angle = 0.0; + double radius = 0.0; + double c[3]; // centre + + while(!((*m_ifs).eof())) + { + get_line(); + int n; + if(sscanf(m_str, "%d", &n) != 1) + { + printf("CDxfRead::ReadArc() Failed to read integer from '%s'\n", m_str); + return false; + } + + std::istringstream ss; + ss.imbue(std::locale("C")); + switch(n){ + case 0: + // next item found, so finish with arc + DerefACI(); + OnReadArc(start_angle, end_angle, radius, c); + return true; + + case 8: // Layer name follows + get_line(); + strcpy(m_layer_name, m_str); + break; + + case 10: + // centre x + get_line(); + ss.str(m_str); ss >> c[0]; c[0] = mm(c[0]); if(ss.fail()) return false; + break; + case 20: + // centre y + get_line(); + ss.str(m_str); ss >> c[1]; c[1] = mm(c[1]); if(ss.fail()) return false; + break; + case 30: + // centre z + get_line(); + ss.str(m_str); ss >> c[2]; c[2] = mm(c[2]); if(ss.fail()) return false; + break; + case 40: + // radius + get_line(); + ss.str(m_str); ss >> radius; radius = mm(radius); if(ss.fail()) return false; + break; + case 50: + // start angle + get_line(); + ss.str(m_str); ss >> start_angle; if(ss.fail()) return false; + break; + case 51: + // end angle + get_line(); + ss.str(m_str); ss >> end_angle; if(ss.fail()) return false; + break; + case 62: + // color index + get_line(); + ss.str(m_str); ss >> m_aci; if(ss.fail()) return false; + break; + case 100: + case 39: + case 210: + case 220: + case 230: + // skip the next line + get_line(); + break; + default: + // skip the next line + get_line(); + break; + } + } + DerefACI(); + OnReadArc(start_angle, end_angle, radius, c); + return false; +} + +bool CDxfRead::ReadSpline() +{ + struct SplineData sd; + sd.norm[0] = 0; + sd.norm[1] = 0; + sd.norm[2] = 1; + sd.degree = 0; + sd.knots = 0; + sd.flag = 0; + sd.control_points = 0; + sd.fit_points = 0; + + double temp_double; + + while(!((*m_ifs).eof())) + { + get_line(); + int n; + if(sscanf(m_str, "%d", &n) != 1) + { + printf("CDxfRead::ReadSpline() Failed to read integer from '%s'\n", m_str); + return false; + } + std::istringstream ss; + ss.imbue(std::locale("C")); + switch(n){ + case 0: + // next item found, so finish with Spline + DerefACI(); + OnReadSpline(sd); + return true; + case 8: // Layer name follows + get_line(); + strcpy(m_layer_name, m_str); + break; + case 62: + // color index + get_line(); + ss.str(m_str); ss >> m_aci; if(ss.fail()) return false; + break; + case 210: + // normal x + get_line(); + ss.str(m_str); ss >> sd.norm[0]; sd.norm[0] = mm(sd.norm[0]); if(ss.fail()) return false; + break; + case 220: + // normal y + get_line(); + ss.str(m_str); ss >> sd.norm[1]; sd.norm[1] = mm(sd.norm[1]); if(ss.fail()) return false; + break; + case 230: + // normal z + get_line(); + ss.str(m_str); ss >> sd.norm[2]; sd.norm[2] = mm(sd.norm[2]); if(ss.fail()) return false; + break; + case 70: + // flag + get_line(); + ss.str(m_str); ss >> sd.flag; if(ss.fail()) return false; + break; + case 71: + // degree + get_line(); + ss.str(m_str); ss >> sd.degree; if(ss.fail()) return false; + break; + case 72: + // knots + get_line(); + ss.str(m_str); ss >> sd.knots; if(ss.fail()) return false; + break; + case 73: + // control points + get_line(); + ss.str(m_str); ss >> sd.control_points; if(ss.fail()) return false; + break; + case 74: + // fit points + get_line(); + ss.str(m_str); ss >> sd.fit_points; if(ss.fail()) return false; + break; + case 12: + // starttan x + get_line(); + ss.str(m_str); ss >> temp_double; if(ss.fail()) return false; + sd.starttanx.push_back(temp_double); + break; + case 22: + // starttan y + get_line(); + ss.str(m_str); ss >> temp_double; if(ss.fail()) return false; + sd.starttany.push_back(temp_double); + break; + case 32: + // starttan z + get_line(); + ss.str(m_str); ss >> temp_double; if(ss.fail()) return false; + sd.starttanz.push_back(temp_double); + break; + case 13: + // endtan x + get_line(); + ss.str(m_str); ss >> temp_double; if(ss.fail()) return false; + sd.endtanx.push_back(temp_double); + break; + case 23: + // endtan y + get_line(); + ss.str(m_str); ss >> temp_double; if(ss.fail()) return false; + sd.endtany.push_back(temp_double); + break; + case 33: + // endtan z + get_line(); + ss.str(m_str); ss >> temp_double; if(ss.fail()) return false; + sd.endtanz.push_back(temp_double); + break; + case 40: + // knot + get_line(); + ss.str(m_str); ss >> temp_double; if(ss.fail()) return false; + sd.knot.push_back(temp_double); + break; + case 41: + // weight + get_line(); + ss.str(m_str); ss >> temp_double; if(ss.fail()) return false; + sd.weight.push_back(temp_double); + break; + case 10: + // control x + get_line(); + ss.str(m_str); ss >> temp_double; if(ss.fail()) return false; + sd.controlx.push_back(temp_double); + break; + case 20: + // control y + get_line(); + ss.str(m_str); ss >> temp_double; if(ss.fail()) return false; + sd.controly.push_back(temp_double); + break; + case 30: + // control z + get_line(); + ss.str(m_str); ss >> temp_double; if(ss.fail()) return false; + sd.controlz.push_back(temp_double); + break; + case 11: + // fit x + get_line(); + ss.str(m_str); ss >> temp_double; if(ss.fail()) return false; + sd.fitx.push_back(temp_double); + break; + case 21: + // fit y + get_line(); + ss.str(m_str); ss >> temp_double; if(ss.fail()) return false; + sd.fity.push_back(temp_double); + break; + case 31: + // fit z + get_line(); + ss.str(m_str); ss >> temp_double; if(ss.fail()) return false; + sd.fitz.push_back(temp_double); + break; + case 42: + case 43: + case 44: + // skip the next line + get_line(); + break; + default: + // skip the next line + get_line(); + break; + } + } + DerefACI(); + OnReadSpline(sd); + return false; +} + + +bool CDxfRead::ReadCircle() +{ + double radius = 0.0; + double c[3]; // centre + + while(!((*m_ifs).eof())) + { + get_line(); + int n; + if(sscanf(m_str, "%d", &n) != 1) + { + printf("CDxfRead::ReadCircle() Failed to read integer from '%s'\n", m_str); + return false; + } + std::istringstream ss; + ss.imbue(std::locale("C")); + switch(n){ + case 0: + // next item found, so finish with Circle + DerefACI(); + OnReadCircle(c, radius); + return true; + case 8: // Layer name follows + get_line(); + strcpy(m_layer_name, m_str); + break; + + case 10: + // centre x + get_line(); + ss.str(m_str); ss >> c[0]; c[0] = mm(c[0]); if(ss.fail()) return false; + break; + case 20: + // centre y + get_line(); + ss.str(m_str); ss >> c[1]; c[1] = mm(c[1]); if(ss.fail()) return false; + break; + case 30: + // centre z + get_line(); + ss.str(m_str); ss >> c[2]; c[2] = mm(c[2]); if(ss.fail()) return false; + break; + case 40: + // radius + get_line(); + ss.str(m_str); ss >> radius; radius = mm(radius); if(ss.fail()) return false; + break; + case 62: + // color index + get_line(); + ss.str(m_str); ss >> m_aci; if(ss.fail()) return false; + break; + + case 100: + case 39: + case 210: + case 220: + case 230: + // skip the next line + get_line(); + break; + default: + // skip the next line + get_line(); + break; + } + } + DerefACI(); + OnReadCircle(c, radius); + return false; +} + + +bool CDxfRead::ReadText() +{ + double c[3]; // coordinate + double height = 0.03082; + + memset( c, 0, sizeof(c) ); + + while(!((*m_ifs).eof())) + { + get_line(); + int n; + if(sscanf(m_str, "%d", &n) != 1) + { + printf("CDxfRead::ReadText() Failed to read integer from '%s'\n", m_str); + return false; + } + std::istringstream ss; + ss.imbue(std::locale("C")); + switch(n){ + case 0: + return false; + case 8: // Layer name follows + get_line(); + strcpy(m_layer_name, m_str); + break; + + case 10: + // centre x + get_line(); + ss.str(m_str); ss >> c[0]; c[0] = mm(c[0]); if(ss.fail()) return false; + break; + case 20: + // centre y + get_line(); + ss.str(m_str); ss >> c[1]; c[1] = mm(c[1]); if(ss.fail()) return false; + break; + case 30: + // centre z + get_line(); + ss.str(m_str); ss >> c[2]; c[2] = mm(c[2]); if(ss.fail()) return false; + break; + case 40: + // text height + get_line(); + ss.str(m_str); ss >> height; height = mm(height); if(ss.fail()) return false; + break; + case 1: + // text + get_line(); + DerefACI(); + OnReadText(c, height * 25.4 / 72.0, m_str); + return(true); + + case 62: + // color index + get_line(); + ss.str(m_str); ss >> m_aci; if(ss.fail()) return false; + break; + + case 100: + case 39: + case 210: + case 220: + case 230: + // skip the next line + get_line(); + break; + default: + // skip the next line + get_line(); + break; + } + } + + return false; +} + + +bool CDxfRead::ReadEllipse() +{ + double c[3]; // centre + double m[3]; //major axis point + double ratio=0; //ratio of major to minor axis + double start=0; //start of arc + double end=0; // end of arc + + while(!((*m_ifs).eof())) + { + get_line(); + int n; + if(sscanf(m_str, "%d", &n) != 1) + { + printf("CDxfRead::ReadEllipse() Failed to read integer from '%s'\n", m_str); + return false; + } + std::istringstream ss; + ss.imbue(std::locale("C")); + switch(n){ + case 0: + // next item found, so finish with Ellipse + DerefACI(); + OnReadEllipse(c, m, ratio, start, end); + return true; + case 8: // Layer name follows + get_line(); + strcpy(m_layer_name, m_str); + break; + + case 10: + // centre x + get_line(); + ss.str(m_str); ss >> c[0]; c[0] = mm(c[0]); if(ss.fail()) return false; + break; + case 20: + // centre y + get_line(); + ss.str(m_str); ss >> c[1]; c[1] = mm(c[1]); if(ss.fail()) return false; + break; + case 30: + // centre z + get_line(); + ss.str(m_str); ss >> c[2]; c[2] = mm(c[2]); if(ss.fail()) return false; + break; + case 11: + // major x + get_line(); + ss.str(m_str); ss >> m[0]; m[0] = mm(m[0]); if(ss.fail()) return false; + break; + case 21: + // major y + get_line(); + ss.str(m_str); ss >> m[1]; m[1] = mm(m[1]); if(ss.fail()) return false; + break; + case 31: + // major z + get_line(); + ss.str(m_str); ss >> m[2]; m[2] = mm(m[2]); if(ss.fail()) return false; + break; + case 40: + // ratio + get_line(); + ss.str(m_str); ss >> ratio; if(ss.fail()) return false; + break; + case 41: + // start + get_line(); + ss.str(m_str); ss >> start; if(ss.fail()) return false; + break; + case 42: + // end + get_line(); + ss.str(m_str); ss >> end; if(ss.fail()) return false; + break; + case 62: + // color index + get_line(); + ss.str(m_str); ss >> m_aci; if(ss.fail()) return false; + break; + case 100: + case 210: + case 220: + case 230: + // skip the next line + get_line(); + break; + default: + // skip the next line + get_line(); + break; + } + } + DerefACI(); + OnReadEllipse(c, m, ratio, start, end); + return false; +} + + +static bool poly_prev_found = false; +static double poly_prev_x; +static double poly_prev_y; +static double poly_prev_z; +static double poly_prev_bulge_found; +static double poly_prev_bulge; +static bool poly_first_found = false; +static double poly_first_x; +static double poly_first_y; +static double poly_first_z; + +static void AddPolyLinePoint(CDxfRead* dxf_read, double x, double y, double z, bool bulge_found, double bulge) +{ + + try { + if(poly_prev_found) + { + bool arc_done = false; + if(poly_prev_bulge_found) + { + double cot = 0.5 * ((1.0 / poly_prev_bulge) - poly_prev_bulge); + double cx = ((poly_prev_x + x) - ((y - poly_prev_y) * cot)) / 2.0; + double cy = ((poly_prev_y + y) + ((x - poly_prev_x) * cot)) / 2.0; + double ps[3] = {poly_prev_x, poly_prev_y, poly_prev_z}; + double pe[3] = {x, y, z}; + double pc[3] = {cx, cy, (poly_prev_z + z)/2.0}; + dxf_read->OnReadArc(ps, pe, pc, poly_prev_bulge >= 0); + arc_done = true; + } + + if(!arc_done) + { + double s[3] = {poly_prev_x, poly_prev_y, poly_prev_z}; + double e[3] = {x, y, z}; + dxf_read->OnReadLine(s, e); + } + } + + poly_prev_found = true; + poly_prev_x = x; + poly_prev_y = y; + poly_prev_z = z; + if(!poly_first_found) + { + poly_first_x = x; + poly_first_y = y; + poly_first_z = z; + poly_first_found = true; + } + poly_prev_bulge_found = bulge_found; + poly_prev_bulge = bulge; + } + catch(...) + { + if (! dxf_read->IgnoreErrors()) throw; // Re-throw it. + } +} + +static void PolyLineStart() +{ + poly_prev_found = false; + poly_first_found = false; +} + +bool CDxfRead::ReadLwPolyLine() +{ + PolyLineStart(); + + bool x_found = false; + bool y_found = false; + double x = 0.0; + double y = 0.0; + double z = 0.0; + bool bulge_found = false; + double bulge = 0.0; + bool closed = false; + int flags; + bool next_item_found = false; + + while(!((*m_ifs).eof()) && !next_item_found) + { + get_line(); + int n; + if(sscanf(m_str, "%d", &n) != 1) + { + printf("CDxfRead::ReadLwPolyLine() Failed to read integer from '%s'\n", m_str); + return false; + } + std::istringstream ss; + ss.imbue(std::locale("C")); + switch(n){ + case 0: + // next item found + + DerefACI(); + if(x_found && y_found){ + // add point + AddPolyLinePoint(this, x, y, z, bulge_found, bulge); + bulge_found = false; + x_found = false; + y_found = false; + } + next_item_found = true; + break; + case 8: // Layer name follows + get_line(); + strcpy(m_layer_name, m_str); + break; + + case 10: + // x + get_line(); + if(x_found && y_found){ + // add point + AddPolyLinePoint(this, x, y, z, bulge_found, bulge); + bulge_found = false; + x_found = false; + y_found = false; + } + ss.str(m_str); ss >> x; x = mm(x); if(ss.fail()) return false; + x_found = true; + break; + case 20: + // y + get_line(); + ss.str(m_str); ss >> y; y = mm(y); if(ss.fail()) return false; + y_found = true; + break; + case 42: + // bulge + get_line(); + ss.str(m_str); ss >> bulge; if(ss.fail()) return false; + bulge_found = true; + break; + case 70: + // flags + get_line(); + if(sscanf(m_str, "%d", &flags) != 1)return false; + closed = ((flags & 1) != 0); + break; + case 62: + // color index + get_line(); + ss.str(m_str); ss >> m_aci; if(ss.fail()) return false; + break; + default: + // skip the next line + get_line(); + break; + } + } + + if(next_item_found) + { + if(closed && poly_first_found) + { + // repeat the first point + DerefACI(); + AddPolyLinePoint(this, poly_first_x, poly_first_y, poly_first_z, false, 0.0); + } + return true; + } + + return false; +} + + +bool CDxfRead::ReadVertex(double *pVertex, bool *bulge_found, double *bulge) +{ + bool x_found = false; + bool y_found = false; + + double x = 0.0; + double y = 0.0; + double z = 0.0; + *bulge = 0.0; + *bulge_found = false; + + pVertex[0] = 0.0; + pVertex[1] = 0.0; + pVertex[2] = 0.0; + + while(!(*m_ifs).eof()) { + get_line(); + int n; + if(sscanf(m_str, "%d", &n) != 1) { + printf("CDxfRead::ReadVertex() Failed to read integer from '%s'\n", m_str); + return false; + } + std::istringstream ss; + ss.imbue(std::locale("C")); + switch(n){ + case 0: + DerefACI(); + put_line(m_str); // read one line too many. put it back. + return(x_found && y_found); + break; + + case 8: // Layer name follows + get_line(); + strcpy(m_layer_name, m_str); + break; + + case 10: + // x + get_line(); + ss.str(m_str); ss >> x; pVertex[0] = mm(x); if(ss.fail()) return false; + x_found = true; + break; + case 20: + // y + get_line(); + ss.str(m_str); ss >> y; pVertex[1] = mm(y); if(ss.fail()) return false; + y_found = true; + break; + case 30: + // z + get_line(); + ss.str(m_str); ss >> z; pVertex[2] = mm(z); if(ss.fail()) return false; + break; + + case 42: + get_line(); + *bulge_found = true; + ss.str(m_str); ss >> *bulge; if(ss.fail()) return false; + break; + case 62: + // color index + get_line(); + ss.str(m_str); ss >> m_aci; if(ss.fail()) return false; + break; + + default: + // skip the next line + get_line(); + break; + } + } + + return false; +} + + + +bool CDxfRead::ReadPolyLine() +{ + PolyLineStart(); + + bool closed = false; + int flags; + bool first_vertex_section_found = false; + double first_vertex[3]; + bool bulge_found; + double bulge; + + while(!(*m_ifs).eof()) + { + get_line(); + int n; + if(sscanf(m_str, "%d", &n) != 1) + { + printf("CDxfRead::ReadPolyLine() Failed to read integer from '%s'\n", m_str); + return false; + } + std::istringstream ss; + ss.imbue(std::locale("C")); + switch(n){ + case 0: + // next item found + DerefACI(); + get_line(); + if (! strcmp(m_str,"VERTEX")) + { + double vertex[3]; + if (CDxfRead::ReadVertex(vertex, &bulge_found, &bulge)) + { + if(!first_vertex_section_found) { + first_vertex_section_found = true; + memcpy(first_vertex, vertex, 3*sizeof(double)); + } + AddPolyLinePoint(this, vertex[0], vertex[1], vertex[2], bulge_found, bulge); + break; + } + } + if (! strcmp(m_str,"SEQEND")) + { + if(closed && first_vertex_section_found) { + AddPolyLinePoint(this, first_vertex[0], first_vertex[1], first_vertex[2], 0, 0); + } + first_vertex_section_found = false; + PolyLineStart(); + return(true); + } + break; + case 70: + // flags + get_line(); + if(sscanf(m_str, "%d", &flags) != 1)return false; + closed = ((flags & 1) != 0); + break; + case 62: + // color index + get_line(); + ss.str(m_str); ss >> m_aci; if(ss.fail()) return false; + break; + default: + // skip the next line + get_line(); + break; + } + } + + return false; +} + +void CDxfRead::OnReadArc(double start_angle, double end_angle, double radius, const double* c){ + double s[3], e[3]; + s[0] = c[0] + radius * cos(start_angle * Pi/180); + s[1] = c[1] + radius * sin(start_angle * Pi/180); + s[2] = c[2]; + e[0] = c[0] + radius * cos(end_angle * Pi/180); + e[1] = c[1] + radius * sin(end_angle * Pi/180); + e[2] = c[2]; + + OnReadArc(s, e, c, true); +} + +void CDxfRead::OnReadCircle(const double* c, double radius){ + double s[3]; + double start_angle = 0; + s[0] = c[0] + radius * cos(start_angle * Pi/180); + s[1] = c[1] + radius * sin(start_angle * Pi/180); + s[2] = c[2]; + + OnReadCircle(s, c, false); //false to change direction because otherwise the arc length is zero +} + +void CDxfRead::OnReadEllipse(const double* c, const double* m, double ratio, double start_angle, double end_angle){ + double major_radius = sqrt(m[0]*m[0] + m[1]*m[1] + m[2]*m[2]); + double minor_radius = major_radius * ratio; + + //Since we only support 2d stuff, we can calculate the rotation from the major axis x and y value only, + //since z is zero, major_radius is the vector length + + double rotation = atan2(m[1]/major_radius,m[0]/major_radius); + + + OnReadEllipse(c, major_radius, minor_radius, rotation, start_angle, end_angle, true); +} + +bool CDxfRead::ReadInsert() +{ + double c[3]; // coordinate + double s[3]; // scale + double rot = 0.0; // rotation + char name[1024]; + s[0] = 1.0; + s[1] = 1.0; + s[2] = 1.0; + + while(!((*m_ifs).eof())) + { + get_line(); + int n; + if(sscanf(m_str, "%d", &n) != 1) + { + printf("CDxfRead::ReadInsert() Failed to read integer from '%s'\n", m_str); + return false; + } + std::istringstream ss; + ss.imbue(std::locale("C")); + switch(n){ + case 0: + // next item found + DerefACI(); + OnReadInsert(c, s, name, rot * Pi/180); + return(true); + case 8: + // Layer name follows + get_line(); + strcpy(m_layer_name, m_str); + break; + case 10: + // coord x + get_line(); + ss.str(m_str); ss >> c[0]; c[0] = mm(c[0]); if(ss.fail()) return false; + break; + case 20: + // coord y + get_line(); + ss.str(m_str); ss >> c[1]; c[1] = mm(c[1]); if(ss.fail()) return false; + break; + case 30: + // coord z + get_line(); + ss.str(m_str); ss >> c[2]; c[2] = mm(c[2]); if(ss.fail()) return false; + break; + case 41: + // scale x + get_line(); + ss.str(m_str); ss >> s[0]; if(ss.fail()) return false; + break; + case 42: + // scale y + get_line(); + ss.str(m_str); ss >> s[1]; if(ss.fail()) return false; + break; + case 43: + // scale z + get_line(); + ss.str(m_str); ss >> s[2]; if(ss.fail()) return false; + break; + case 50: + // rotation + get_line(); + ss.str(m_str); ss >> rot; if(ss.fail()) return false; + break; + case 2: + // block name + get_line(); + strcpy(name, m_str); + break; + case 62: + // color index + get_line(); + ss.str(m_str); ss >> m_aci; if(ss.fail()) return false; + break; + case 100: + case 39: + case 210: + case 220: + case 230: + // skip the next line + get_line(); + break; + default: + // skip the next line + get_line(); + break; + } + } + return false; +} + +void CDxfRead::get_line() +{ + if (m_unused_line[0] != '\0') + { + strcpy(m_str, m_unused_line); + memset( m_unused_line, '\0', sizeof(m_unused_line)); + return; + } + + m_ifs->getline(m_str, 1024); + + char str[1024]; + int len = strlen(m_str); + int j = 0; + bool non_white_found = false; + for(int i = 0; i 0) + { + result.append(m_section_name); + } + + if (strlen(m_block_name) > 0) + { + result.append(" "); + result.append(m_block_name); + } + + if (strlen(m_layer_name) > 0) + { + result.append(" "); + result.append(m_layer_name); + } + + return(result); +} + diff --git a/src/Mod/Path/libarea/dxf.h b/src/Mod/Path/libarea/dxf.h new file mode 100644 index 000000000..0890fe8fe --- /dev/null +++ b/src/Mod/Path/libarea/dxf.h @@ -0,0 +1,158 @@ +// dxf.h +// Copyright (c) 2009, Dan Heeks +// This program is released under the BSD license. See the file COPYING for details. +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//Following is required to be defined on Ubuntu with OCC 6.3.1 +#ifndef HAVE_IOSTREAM +#define HAVE_IOSTREAM +#endif + +typedef int Aci_t; // AutoCAD color index + +typedef enum +{ + eUnspecified = 0, // Unspecified (No units) + eInches, + eFeet, + eMiles, + eMillimeters, + eCentimeters, + eMeters, + eKilometers, + eMicroinches, + eMils, + eYards, + eAngstroms, + eNanometers, + eMicrons, + eDecimeters, + eDekameters, + eHectometers, + eGigameters, + eAstronomicalUnits, + eLightYears, + eParsecs +} eDxfUnits_t; + + +struct SplineData +{ + double norm[3]; + int degree; + int knots; + int control_points; + int fit_points; + int flag; + std::list starttanx; + std::list starttany; + std::list starttanz; + std::list endtanx; + std::list endtany; + std::list endtanz; + std::list knot; + std::list weight; + std::list controlx; + std::list controly; + std::list controlz; + std::list fitx; + std::list fity; + std::list fitz; +}; + +class CDxfWrite{ +private: + std::ofstream* m_ofs; + bool m_fail; + +public: + CDxfWrite(const char* filepath); + ~CDxfWrite(); + + bool Failed(){return m_fail;} + + void WriteLine(const double* s, const double* e, const char* layer_name ); + void WritePoint(const double*, const char*); + void WriteArc(const double* s, const double* e, const double* c, bool dir, const char* layer_name ); + void WriteEllipse(const double* c, double major_radius, double minor_radius, double rotation, double start_angle, double end_angle, bool dir, const char* layer_name ); + void WriteCircle(const double* c, double radius, const char* layer_name ); +}; + +// derive a class from this and implement it's virtual functions +class CDxfRead{ +private: + std::ifstream* m_ifs; + + bool m_fail; + char m_str[1024]; + char m_unused_line[1024]; + eDxfUnits_t m_eUnits; + char m_layer_name[1024]; + char m_section_name[1024]; + char m_block_name[1024]; + bool m_ignore_errors; + + + typedef std::map< std::string,Aci_t > LayerAciMap_t; + LayerAciMap_t m_layer_aci; // layer names -> layer color aci map + + bool ReadUnits(); + bool ReadLayer(); + bool ReadLine(); + bool ReadText(); + bool ReadArc(); + bool ReadCircle(); + bool ReadEllipse(); + bool ReadPoint(); + bool ReadSpline(); + bool ReadLwPolyLine(); + bool ReadPolyLine(); + bool ReadVertex(double *pVertex, bool *bulge_found, double *bulge); + void OnReadArc(double start_angle, double end_angle, double radius, const double* c); + void OnReadCircle(const double* c, double radius); + void OnReadEllipse(const double* c, const double* m, double ratio, double start_angle, double end_angle); + bool ReadInsert(); + + void get_line(); + void put_line(const char *value); + void DerefACI(); + +protected: + Aci_t m_aci; // manifest color name or 256 for layer color + +public: + CDxfRead(const char* filepath); // this opens the file + ~CDxfRead(); // this closes the file + + bool Failed(){return m_fail;} + void DoRead(const bool ignore_errors = false); // this reads the file and calls the following functions + + double mm( const double & value ) const; + + bool IgnoreErrors() const { return(m_ignore_errors); } + + virtual void OnReadLine(const double* s, const double* e){} + virtual void OnReadPoint(const double* s){} + virtual void OnReadText(const double* point, const double height, const char* text){} + virtual void OnReadArc(const double* s, const double* e, const double* c, bool dir){} + virtual void OnReadCircle(const double* s, const double* c, bool dir){} + virtual void OnReadEllipse(const double* c, double major_radius, double minor_radius, double rotation, double start_angle, double end_angle, bool dir){} + virtual void OnReadSpline(struct SplineData& sd){} + virtual void OnReadInsert(const double* point, const double* scale, const char* name, double rotation){} + virtual void AddGraphics() const { } + + std::string LayerName() const; + +}; diff --git a/src/Mod/Path/libarea/kurve/Construction.cpp b/src/Mod/Path/libarea/kurve/Construction.cpp index 7d387ee61..f8bba29c5 100644 --- a/src/Mod/Path/libarea/kurve/Construction.cpp +++ b/src/Mod/Path/libarea/kurve/Construction.cpp @@ -1,35 +1,11 @@ // *************************************************************************************************************************************** // Point, CLine & Circle classes part of geometry.lib +// g.j.hawkesford August 2006 for Camtek Gmbh +// +// This program is released under the BSD license. See the file COPYING for details. +// // *************************************************************************************************************************************** -/*============================== -Copyright (c) 2006 g.j.hawkesford - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -==============================*/ - - - #include "geometry.h" using namespace geoff_geometry; @@ -42,7 +18,6 @@ namespace geoff_geometry { double RESOLUTION = 1.0e-06; // dummy functions - const wchar_t* getMessage(const wchar_t* original, int messageGroup, int stringID){return original;} const wchar_t* getMessage(const wchar_t* original){return original;} void FAILURE(const wchar_t* str){throw(str);} void FAILURE(const std::wstring& str){throw(str);} @@ -382,7 +357,7 @@ namespace geoff_geometry { // circle methods // *************************************************************************************************************************************** - Circle::Circle(const Point& p, double rad, bool okay){ + Circle::Circle(const Point& p, double rad){ // Circle pc = p; radius = rad; @@ -410,7 +385,7 @@ namespace geoff_geometry { Circle Circle::Transform(Matrix& m) { // transform Point p0 = this->pc; double scale; - if(m.GetScale(scale) == false) FAILURE(getMessage(L"Differential Scale not allowed for this method", GEOMETRY_ERROR_MESSAGES, MES_DIFFSCALE)); + if(m.GetScale(scale) == false) FAILURE(getMessage(L"Differential Scale not allowed for this method")); return Circle(p0.Transform(m), radius * scale); } @@ -485,7 +460,7 @@ namespace geoff_geometry { Point On(const Circle& c, const Point& p) { // returns point that is nearest to c from p double r = p.Dist(c.pc); - if(r < TOLERANCE) FAILURE(getMessage(L",Point on Circle centre - On(Circle& c, Point& p)", GEOMETRY_ERROR_MESSAGES, MES_POINTONCENTRE)); + if(r < TOLERANCE) FAILURE(getMessage(L",Point on Circle centre - On(Circle& c, Point& p)")); return(Mid(p, c.pc, (r - c.radius) / r)); } @@ -665,7 +640,7 @@ namespace geoff_geometry { if(!s2.ok) return Thro(p0, p2); // p1 & p2 coincident Point p = Intof(Normal(s0, Mid(p0, p1)), Normal(s1, Mid(p0, p2))); - return (p.ok)? Circle(p, p0.Dist(p), true) : INVALID_CIRCLE; + return (p.ok)? Circle(p, p0.Dist(p)) : INVALID_CIRCLE; } Circle Tanto(int NF, int AT0, const CLine& s0, int AT1, const Circle &c1, double rad) { // circle tanto cline & circle with radius @@ -810,7 +785,8 @@ namespace geoff_geometry { Plane::Plane(double dist, const Vector3d& n) { normal = n; double mag = normal.normalise(); - if((ok = (normal != NULL_VECTOR))) d = dist / mag; + ok = (normal != NULL_VECTOR); + if(ok) d = dist / mag; } double Plane::Dist(const Point3d& p)const{ diff --git a/src/Mod/Path/libarea/kurve/Finite.cpp b/src/Mod/Path/libarea/kurve/Finite.cpp index ad2755a52..cb53c0146 100644 --- a/src/Mod/Path/libarea/kurve/Finite.cpp +++ b/src/Mod/Path/libarea/kurve/Finite.cpp @@ -1,36 +1,13 @@ -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// finite intersections -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -/*============================== -Copyright (c) 2006 g.j.hawkesford - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -==============================*/ +// written by g.j.hawkesford 2006 for Camtek Gmbh +// +// This program is released under the BSD license. See the file COPYING for details. +// #include "geometry.h" - +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// finite intersections +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #ifndef WIN32 #define __min(a,b) ((aNear(Point3d(0.,0.,0.)); + Point3d p1 = this->Near(Point3d(0.,0.,0.)); if(tmMirrored->m_unit == false) tmMirrored->Unit(); double nx = this->normal.getx(); diff --git a/src/Mod/Path/libarea/kurve/geometry.h b/src/Mod/Path/libarea/kurve/geometry.h index fd8f0f00b..9440030a8 100644 --- a/src/Mod/Path/libarea/kurve/geometry.h +++ b/src/Mod/Path/libarea/kurve/geometry.h @@ -1,34 +1,14 @@ + ///////////////////////////////////////////////////////////////////////////////////////// + // geometry.lib header -// modified with 2d & 3d vector methods 2006 + +// g.j.hawkesford August 2003 +// modified with 2d & 3d vector methods 2006 +// +// This program is released under the BSD license. See the file COPYING for details. +// ///////////////////////////////////////////////////////////////////////////////////////// - -/*============================== -Copyright (c) 2006 g.j.hawkesford - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -==============================*/ - #pragma once #ifdef WIN32 #pragma warning( disable : 4996 ) @@ -130,7 +110,6 @@ inline bool FNEZ(double a, double tolerance = TIGHT_TOLERANCE) {return fabs(a) > #define ACW 1 // anti-clockwise #define CW -1 // clockwise - const wchar_t* getMessage(const wchar_t* original, int messageGroup, int stringID); const wchar_t* getMessage(const wchar_t* original); // dummy void FAILURE(const wchar_t* str); void FAILURE(const std::wstring& str); @@ -262,7 +241,7 @@ inline bool FNEZ(double a, double tolerance = TIGHT_TOLERANCE) {return fabs(a) > #define INVALID_POINT Point(9.9999999e50, 0, false) #define INVALID_POINT3D Point3d(9.9999999e50, 0, 0, false) #define INVALID_CLINE CLine(INVALID_POINT, 1, 0, false) -#define INVALID_CIRCLE Circle(INVALID_POINT, 0, false) +#define INVALID_CIRCLE Circle(INVALID_POINT, 0) // 3d point class class Point3d { @@ -335,7 +314,7 @@ inline bool FNEZ(double a, double tolerance = TIGHT_TOLERANCE) {return fabs(a) > inline const Vector2d& operator+=(const Vector2d &v){dx += v.dx; dy += v.dy; return *this;} // v1 += v0; inline Vector2d operator-(const Vector2d &v)const{return Vector2d( dx - v.dx, dy - v.dy);} // v2 = v0 - v1; - inline const Vector2d& operator-=(const Vector2d &v){dx -= v.dx; dy -= v.dy; return *this;} // v1 -= v0; + inline const Vector2d& operator-=(const Vector2d &v){dx -= v.dx; dy =- v.dy; return *this;} // v1 -= v0; inline Vector2d operator-(const double d){ return Vector2d(dx - d, dy - d); }; inline const Vector2d operator-(void)const{return Vector2d(-dx, -dy);} // v1 = -v0; (unary minus) @@ -404,7 +383,7 @@ inline bool FNEZ(double a, double tolerance = TIGHT_TOLERANCE) {return fabs(a) > const Vector3d& operator+=(const Vector3d &v){dx += v.dx; dy += v.dy; dz += v.dz; return *this;} // v1 += v0; Vector3d operator-(const Vector3d &v)const{return Vector3d( dx - v.dx, dy - v.dy, dz - v.dz);} // v2 = v0 - v1; const Vector3d& operator-=(const Vector3d &v){ - dx -= v.dx; dy -= v.dy; dz -= v.dz; return *this;} // v1 -= v0; + dx -= v.dx; dy =- v.dy; dz = -v.dz; return *this;} // v1 -= v0; const Vector3d operator-(void)const{return Vector3d(-dx, -dy, -dz);} // v1 = -v0; (unary minus) @@ -499,8 +478,8 @@ inline bool FNEZ(double a, double tolerance = TIGHT_TOLERANCE) {return fabs(a) > // constructors etc... inline Circle() {ok = false;}; - Circle( const Point& p, double r, bool okay = true); // Circle c1(Point(10,30), 20); - Circle( const Point& p, const Point& pc); // Circle c1(p[222], p[223]); + Circle( const Point& p, double r); // Circle c1(Point(10,30), 20); + Circle( const Point& p, const Point& pc); // Circle c1(p[222], p[223]); Circle( const Circle& c ){*this = c;} // copy constructor Circle c1(c2); Circle( const Span& sp); // constructor @@ -952,7 +931,7 @@ inline bool FNEZ(double a, double tolerance = TIGHT_TOLERANCE) {return fabs(a) > int Intof(const Span& sp0 , const Span& sp1, Point& p0, Point& p1, double t[4]); int LineLineIntof(const Span& L0 , const Span& L1, Point& p, double t[2]); int LineArcIntof(const Span& line, const Span& arc, Point& p0, Point& p1, double t[4]); - int ArcArcIntof(const Span& arc0, const Span& arc1, Point& pLeft, Point& pRight, double t[4]); + int ArcArcIntof(const Span& arc0, const Span& arc1, Point& pLeft, Point& pRight); bool OnSpan(const Span& sp, const Point& p); bool OnSpan(const Span& sp, const Point& p, bool nearPoints, Point& pNear, Point& pOnSpan); // function returns true if pNear == pOnSpan diff --git a/src/Mod/Path/libarea/kurve/kurve.cpp b/src/Mod/Path/libarea/kurve/kurve.cpp index 41c3cb0d7..61d096cda 100644 --- a/src/Mod/Path/libarea/kurve/kurve.cpp +++ b/src/Mod/Path/libarea/kurve/kurve.cpp @@ -1,32 +1,7 @@ -//////////////////////////////////////////////////////////////////////////////////////////////// -// kurve -//////////////////////////////////////////////////////////////////////////////////////////////// - -/*============================== -Copyright (c) 2006 g.j.hawkesford - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -==============================*/ +// written by g.j.hawkesford 2006 for Camtek Gmbh +// +// This program is released under the BSD license. See the file COPYING for details. +// #include "geometry.h" using namespace geoff_geometry; @@ -35,6 +10,11 @@ using namespace geoff_geometry; #include "postoutput.h" #endif + +//////////////////////////////////////////////////////////////////////////////////////////////// +// kurve +//////////////////////////////////////////////////////////////////////////////////////////////// + namespace geoff_geometry { SpanVertex::SpanVertex() { @@ -696,7 +676,7 @@ return; void Kurve::Replace(int vertexnumber, int type, const Point& p0, const Point& pc, int ID) { // replace a span #ifdef _DEBUG - if(this == NULL || vertexnumber > m_nVertices) FAILURE(getMessage(L"Kurve::Replace - vertexNumber out of range", GEOMETRY_ERROR_MESSAGES, MES_BAD_VERTEX_NUMBER)); + if(this == NULL || vertexnumber > m_nVertices) FAILURE(getMessage(L"Kurve::Replace - vertexNumber out of range")); #endif SpanVertex* p = (SpanVertex*) m_spans[vertexnumber / SPANSTORAGE]; p->Add(vertexnumber % SPANSTORAGE, type, p0, pc, ID); @@ -706,7 +686,7 @@ return; void Kurve::ModifyIndex(int vertexnumber, WireExtraData* i) { // replace an index #ifdef _DEBUG - if(this == NULL || vertexnumber > m_nVertices) FAILURE(getMessage(L"Kurve::ModifyIndex - vertexNumber out of range", GEOMETRY_ERROR_MESSAGES, MES_BAD_VERTEX_NUMBER)); + if(this == NULL || vertexnumber > m_nVertices) FAILURE(getMessage(L"Kurve::ModifyIndex - vertexNumber out of range")); #endif SpanVertex* p = (SpanVertex*) m_spans[vertexnumber / SPANSTORAGE]; p->Add(vertexnumber % SPANSTORAGE, i); @@ -743,7 +723,7 @@ return; int Kurve::Get(int vertexnumber, Point& pe, Point& pc) const { // returns spantype with end / centre by reference - if(vertexnumber < 0 || vertexnumber >= m_nVertices) FAILURE(getMessage(L"Kurve::Get - vertexNumber out of range", GEOMETRY_ERROR_MESSAGES, MES_BAD_VERTEX_NUMBER)); + if(vertexnumber < 0 || vertexnumber >= m_nVertices) FAILURE(getMessage(L"Kurve::Get - vertexNumber out of range")); if(m_isReversed == true) { int revVertexnumber = m_nVertices - 1 - vertexnumber; SpanVertex* p = (SpanVertex*)m_spans[revVertexnumber / SPANSTORAGE]; @@ -765,14 +745,14 @@ return; } int Kurve::GetSpanID(int vertexnumber) const { // for spanID (wire offset) - if(vertexnumber < 0 || vertexnumber >= m_nVertices) FAILURE(getMessage(L"Kurve::Get - vertexNumber out of range", GEOMETRY_ERROR_MESSAGES, MES_BAD_VERTEX_NUMBER)); + if(vertexnumber < 0 || vertexnumber >= m_nVertices) FAILURE(getMessage(L"Kurve::Get - vertexNumber out of range")); if(m_isReversed == true) vertexnumber = m_nVertices - 1 - vertexnumber; SpanVertex* p = (SpanVertex*)m_spans[vertexnumber / SPANSTORAGE]; return p->GetSpanID(vertexnumber % SPANSTORAGE); } int Kurve::Get(int spannumber, Span& sp, bool returnSpanProperties, bool transform) const { // returns span data and optional properties - the function returns as the span type - if(spannumber < 1 || spannumber > m_nVertices) FAILURE(getMessage(L"Kurve::Get - vertexNumber out of range", GEOMETRY_ERROR_MESSAGES, MES_BAD_VERTEX_NUMBER)); + if(spannumber < 1 || spannumber > m_nVertices) FAILURE(getMessage(L"Kurve::Get - vertexNumber out of range")); if(m_nVertices < 2) return -99; int spanVertexNumber = spannumber - 1; @@ -798,7 +778,7 @@ return; #if 0 int Kurve::Get(int spannumber, Span3d& sp, bool returnSpanProperties, bool transform) const { // returns span data and optional properties - the function returns as the span type - if(spannumber < 1 || spannumber > m_nVertices) FAILURE(getMessage(L"Kurve::Get - vertexNumber out of range", GEOMETRY_ERROR_MESSAGES, MES_BAD_VERTEX_NUMBER)); + if(spannumber < 1 || spannumber > m_nVertices) FAILURE(getMessage(L"Kurve::Get - vertexNumber out of range")); if(m_nVertices < 2) return -99; int spanVertexNumber = spannumber - 1; @@ -832,7 +812,8 @@ return; } void Span::SetProperties(bool returnProperties) { - if((returnSpanProperties = returnProperties)) { + returnSpanProperties = returnProperties; + if(returnSpanProperties) { // return span properties if(dir) { // arc properties @@ -847,7 +828,7 @@ return; double radCheck = ve.normalise(); // if(FNE(radius, radCheck, geoff_geometry::TOLERANCE * 0.5)){ if(FNE(radius, radCheck, geoff_geometry::TOLERANCE)){ - FAILURE(getMessage(L"Invalid Geometry - Radii mismatch - SetProperties", GEOMETRY_ERROR_MESSAGES, MES_INVALIDARC)); + FAILURE(getMessage(L"Invalid Geometry - Radii mismatch - SetProperties")); } length = 0.0; @@ -998,10 +979,10 @@ return; Kurve temp; bool wrapped = false; - int nSpans = 0; int spanno = startSpanno; Span sp; - while(1) { + for(int nSpans = 0; nSpans <= this->nSpans(); nSpans++) + { this->Get(spanno, sp, false, true); if(spanno == startSpanno && wrapped == false) { temp.Start(*pNewStart); @@ -1015,8 +996,7 @@ return; } spanno++; - nSpans++; - if(nSpans > this->nSpans()) break; + if(spanno > this->nSpans()) { if(this->Closed() == false) break; spanno = 1; @@ -1041,10 +1021,11 @@ return; if(spLast.p1 == *pNewEnd) return; } Kurve temp; - - int spanno = 1; + Span sp; - while(1) { + + for(int spanno = 1; spanno != (endSpanno + 1); spanno++) + { this->Get(spanno, sp, false, true); if(spanno == 1) { temp.Start(sp.p0); @@ -1067,7 +1048,7 @@ return; min = Point(1.0e61, 1.0e61); max = Point(-1.0e61, -1.0e61); - if(!GetScale(xscale)) FAILURE(getMessage(L"Differential Scale not allowed for this method", GEOMETRY_ERROR_MESSAGES, MES_DIFFSCALE)); // differential scale + if(!GetScale(xscale)) FAILURE(getMessage(L"Differential Scale not allowed for this method")); // differential scale Span sp; for(int i = 1; i < m_nVertices; i++) { Get(i, sp, true, true); @@ -1118,7 +1099,7 @@ return; double perim = 0; Span sp; double xscale = 1.0; - if(!GetScale(xscale)) FAILURE(getMessage(L"Differential Scale not allowed for this method", GEOMETRY_ERROR_MESSAGES, MES_DIFFSCALE)); // differential scale + if(!GetScale(xscale)) FAILURE(getMessage(L"Differential Scale not allowed for this method")); // differential scale if(m_nVertices > 1) { for(int i = 1; i < m_nVertices; i++) @@ -1133,7 +1114,7 @@ return; Span sp; if(Closed()) { - if(!GetScale(xscale)) FAILURE(getMessage(L"Differential Scale not allowed for this method", GEOMETRY_ERROR_MESSAGES, MES_DIFFSCALE)); // differential scale + if(!GetScale(xscale)) FAILURE(getMessage(L"Differential Scale not allowed for this method")); // differential scale for(int i = 1; i < m_nVertices; i++) { if(Get(i, sp, true)) area += ( 0.5 * ((sp.pc.x - sp.p0.x) * (sp.pc.y + sp.p0.y) - (sp.pc.x - sp.p1.x) * (sp.pc.y + sp.p1.y) - sp.angle * sp.radius * sp.radius)); @@ -1345,7 +1326,7 @@ return; return m_nVertices - kReduced.m_nVertices; #else - int dir1 = 0, dir2 = 0; + int dir1, dir2 = 0; Point p0, p1, p2, pc0, pc1, pc2; int vertex = 0; int dir0 = Get(vertex++, p0, pc0); // first vertex diff --git a/src/Mod/Path/libarea/kurve/offset.cpp b/src/Mod/Path/libarea/kurve/offset.cpp index 2a016fcc5..163d71ec1 100644 --- a/src/Mod/Path/libarea/kurve/offset.cpp +++ b/src/Mod/Path/libarea/kurve/offset.cpp @@ -1,34 +1,11 @@ //////////////////////////////////////////////////////////////////////////////////////////////// // 2d geometry classes - implements 2d kurve offset for use in dll // +// g.j.hawkesford August 2003 +// +// This program is released under the BSD license. See the file COPYING for details. +// //////////////////////////////////////////////////////////////////////////////////////////////// - -/*============================== -Copyright (c) 2003 g.j.hawkesford - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -==============================*/ - #include "geometry.h" using namespace geoff_geometry;