From ad57c0098a1281aef878b7b680421c40592d77fb Mon Sep 17 00:00:00 2001 From: Koen Schmeets Date: Mon, 9 Jan 2023 12:20:19 +0100 Subject: [PATCH 1/4] Add and run clang-format --- .clang-format | 216 ++++++ .editorconfig | 12 + src/algo/adaptivewaterline.cpp | 241 ++++--- src/algo/adaptivewaterline.hpp | 106 ++- src/algo/batchpushcutter.cpp | 135 ++-- src/algo/batchpushcutter.hpp | 95 +-- src/algo/clsurface.hpp | 375 +++++----- src/algo/fiber.cpp | 87 ++- src/algo/fiber.hpp | 113 ++- src/algo/fiberpushcutter.cpp | 77 +-- src/algo/fiberpushcutter.hpp | 76 +- src/algo/interval.cpp | 76 +- src/algo/interval.hpp | 121 ++-- src/algo/operation.hpp | 199 +++--- src/algo/simple_weave.cpp | 322 ++++----- src/algo/simple_weave.hpp | 63 +- src/algo/smart_weave.cpp | 389 ++++++----- src/algo/smart_weave.hpp | 54 +- src/algo/tsp.hpp | 113 ++- src/algo/waterline.cpp | 128 ++-- src/algo/waterline.hpp | 102 ++- src/algo/weave.cpp | 96 ++- src/algo/weave.hpp | 67 +- src/algo/weave_typedef.hpp | 102 ++- src/algo/zigzag.hpp | 137 ++-- src/common/brent_zero.hpp | 124 ++-- src/common/clfilter.hpp | 57 +- src/common/halfedgediagram.hpp | 725 +++++++++----------- src/common/kdnode.hpp | 143 ++-- src/common/kdtree.hpp | 496 +++++++------ src/common/lineclfilter.cpp | 46 +- src/common/lineclfilter.hpp | 37 +- src/common/numeric.cpp | 85 +-- src/common/numeric.hpp | 48 +- src/cutters/ballcutter.cpp | 114 +-- src/cutters/ballcutter.hpp | 52 +- src/cutters/bullcutter.cpp | 140 ++-- src/cutters/bullcutter.hpp | 60 +- src/cutters/compositecutter.cpp | 289 ++++---- src/cutters/compositecutter.hpp | 186 +++-- src/cutters/conecutter.cpp | 346 +++++----- src/cutters/conecutter.hpp | 84 ++- src/cutters/cylcutter.cpp | 65 +- src/cutters/cylcutter.hpp | 50 +- src/cutters/ellipse.cpp | 332 +++++---- src/cutters/ellipse.hpp | 215 +++--- src/cutters/ellipseposition.cpp | 50 +- src/cutters/ellipseposition.hpp | 88 +-- src/cutters/millingcutter.cpp | 388 +++++------ src/cutters/millingcutter.hpp | 303 ++++---- src/dropcutter/adaptivepathdropcutter.cpp | 71 +- src/dropcutter/adaptivepathdropcutter.hpp | 109 ++- src/dropcutter/batchdropcutter.cpp | 192 +++--- src/dropcutter/batchdropcutter.hpp | 77 +-- src/dropcutter/pathdropcutter.cpp | 44 +- src/dropcutter/pathdropcutter.hpp | 85 ++- src/dropcutter/pointdropcutter.cpp | 54 +- src/dropcutter/pointdropcutter.hpp | 53 +- src/emscriptenlib/emscriptenlib.cpp | 61 +- src/geo/arc.cpp | 81 ++- src/geo/arc.hpp | 90 +-- src/geo/bbox.cpp | 111 ++- src/geo/bbox.hpp | 99 ++- src/geo/ccpoint.cpp | 60 +- src/geo/ccpoint.hpp | 90 +-- src/geo/clpoint.cpp | 83 +-- src/geo/clpoint.hpp | 84 ++- src/geo/line.cpp | 43 +- src/geo/line.hpp | 64 +- src/geo/path.cpp | 37 +- src/geo/path.hpp | 131 ++-- src/geo/point.cpp | 283 +++----- src/geo/point.hpp | 242 ++++--- src/geo/stlreader.cpp | 226 +++--- src/geo/stlreader.hpp | 42 +- src/geo/stlsurf.cpp | 55 +- src/geo/stlsurf.hpp | 57 +- src/geo/triangle.cpp | 103 ++- src/geo/triangle.hpp | 93 ++- src/manual.hpp | 215 +++--- src/nodejslib/adaptivepathdropcutter_js.cpp | 78 +-- src/nodejslib/adaptivepathdropcutter_js.hpp | 6 +- src/nodejslib/adaptivewaterline_js.cpp | 70 +- src/nodejslib/adaptivewaterline_js.hpp | 5 +- src/nodejslib/ballcutter_js.cpp | 19 +- src/nodejslib/ballcutter_js.hpp | 5 +- src/nodejslib/bbox_js.cpp | 14 +- src/nodejslib/bbox_js.hpp | 5 +- src/nodejslib/bullcutter_js.cpp | 19 +- src/nodejslib/bullcutter_js.hpp | 5 +- src/nodejslib/conecutter_js.cpp | 19 +- src/nodejslib/conecutter_js.hpp | 5 +- src/nodejslib/cylcutter_js.cpp | 21 +- src/nodejslib/cylcutter_js.hpp | 5 +- src/nodejslib/line_js.cpp | 51 +- src/nodejslib/line_js.hpp | 17 +- src/nodejslib/nodejslib.cpp | 52 +- src/nodejslib/path_js.cpp | 54 +- src/nodejslib/path_js.hpp | 19 +- src/nodejslib/pathdropcutter_js.cpp | 73 +- src/nodejslib/pathdropcutter_js.hpp | 5 +- src/nodejslib/point_js.cpp | 142 ++-- src/nodejslib/point_js.hpp | 31 +- src/nodejslib/stlreader_js.cpp | 16 +- src/nodejslib/stlreader_js.hpp | 5 +- src/nodejslib/stlsurf_js.cpp | 32 +- src/nodejslib/stlsurf_js.hpp | 6 +- src/nodejslib/triangle_js.cpp | 22 +- src/nodejslib/triangle_js.hpp | 5 +- src/nodejslib/waterline_js.cpp | 65 +- src/nodejslib/waterline_js.hpp | 8 +- src/ocl.cpp | 15 +- src/ocl.hpp | 9 +- src/pythonlib/adaptivepathdropcutter_py.hpp | 45 +- src/pythonlib/adaptivewaterline_py.hpp | 85 ++- src/pythonlib/batchdropcutter_py.hpp | 67 +- src/pythonlib/batchpushcutter_py.hpp | 129 ++-- src/pythonlib/fiber_py.hpp | 47 +- src/pythonlib/lineclfilter_py.hpp | 41 +- src/pythonlib/millingcutter_py.hpp | 119 ++-- src/pythonlib/ocl.cpp | 57 +- src/pythonlib/ocl_algo.cpp | 133 ++-- src/pythonlib/ocl_cutters.cpp | 94 +-- src/pythonlib/ocl_dropcutter.cpp | 49 +- src/pythonlib/ocl_geometry.cpp | 140 ++-- src/pythonlib/path_py.hpp | 92 ++- src/pythonlib/pathdropcutter_py.hpp | 43 +- src/pythonlib/stlsurf_py.hpp | 83 ++- src/pythonlib/triangle_py.hpp | 74 +- src/pythonlib/waterline_py.hpp | 86 ++- src/pythonlib/weave_py.h | 143 ++-- src/pythonlib/weave_py.hpp | 112 ++- src/pythonlib/zigzag_py.hpp | 28 +- 133 files changed, 6586 insertions(+), 7044 deletions(-) create mode 100644 .clang-format create mode 100644 .editorconfig diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..a2d84ede --- /dev/null +++ b/.clang-format @@ -0,0 +1,216 @@ +--- +Language: Cpp +# BasedOnStyle: LLVM +AccessModifierOffset: -2 +AlignAfterOpenBracket: Align +AlignArrayOfStructures: None +AlignConsecutiveAssignments: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + PadOperators: true +AlignConsecutiveBitFields: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + PadOperators: false +AlignConsecutiveDeclarations: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + PadOperators: false +AlignConsecutiveMacros: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + PadOperators: false +AlignEscapedNewlines: Right +AlignOperands: Align +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortEnumsOnASingleLine: true +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AllowShortLambdasOnASingleLine: All +AllowShortIfStatementsOnASingleLine: Never +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: MultiLine +AttributeMacros: + - __capability +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: Never + AfterEnum: false + AfterFunction: false + AfterNamespace: true + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeConceptDeclarations: Always +BreakBeforeBraces: Attach +BreakBeforeInheritanceComma: false +BreakInheritanceList: BeforeColon +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeColon +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 120 +CommentPragmas: '^ IWYU pragma:' +QualifierAlignment: Leave +CompactNamespaces: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DeriveLineEnding: true +DerivePointerAlignment: false +DisableFormat: false +EmptyLineAfterAccessModifier: Never +EmptyLineBeforeAccessModifier: LogicalBlock +ExperimentalAutoDetectBinPacking: false +PackConstructorInitializers: BinPack +BasedOnStyle: '' +ConstructorInitializerAllOnOneLineOrOnePerLine: false +AllowAllConstructorInitializersOnNextLine: true +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IfMacros: + - KJ_IF_MAYBE +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + SortPriority: 0 + CaseSensitive: false + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + SortPriority: 0 + CaseSensitive: false + - Regex: '.*' + Priority: 1 + SortPriority: 0 + CaseSensitive: false +IncludeIsMainRegex: '(Test)?$' +IncludeIsMainSourceRegex: '' +IndentAccessModifiers: false +IndentCaseLabels: false +IndentCaseBlocks: false +IndentGotoLabels: true +IndentPPDirectives: None +IndentExternBlock: AfterExternBlock +IndentRequiresClause: true +IndentWidth: 4 +IndentWrappedFunctionNames: false +InsertBraces: false +InsertTrailingCommas: None +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: true +LambdaBodyIndentation: Signature +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Auto +ObjCBlockIndentWidth: 2 +ObjCBreakBeforeNestedBlockParam: true +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakOpenParenthesis: 0 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 60 +PenaltyIndentedWhitespace: 0 +PointerAlignment: Right +PPIndentWidth: -1 +ReferenceAlignment: Pointer +ReflowComments: true +RemoveBracesLLVM: false +RequiresClausePosition: OwnLine +SeparateDefinitionBlocks: Leave +ShortNamespaceLines: 1 +SortIncludes: CaseSensitive +SortJavaStaticImport: Before +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCaseColon: false +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeParensOptions: + AfterControlStatements: true + AfterForeachMacros: true + AfterFunctionDefinitionName: false + AfterFunctionDeclarationName: false + AfterIfMacros: true + AfterOverloadedOperator: false + AfterRequiresInClause: false + AfterRequiresInExpression: false + BeforeNonEmptyParentheses: false +SpaceAroundPointerQualifiers: Default +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyBlock: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: Never +SpacesInConditionalStatement: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInLineCommentPrefix: + Minimum: 1 + Maximum: -1 +SpacesInParentheses: false +SpacesInSquareBrackets: false +SpaceBeforeSquareBrackets: false +BitFieldColonSpacing: Both +Standard: Latest +StatementAttributeLikeMacros: + - Q_EMIT +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 4 +UseCRLF: false +UseTab: Never +WhitespaceSensitiveMacros: + - STRINGIZE + - PP_STRINGIZE + - BOOST_PP_STRINGIZE + - NS_SWIFT_NAME + - CF_SWIFT_NAME +... + diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..8ca73a92 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +# top-most EditorConfig file +root = true + +[*] +trim_trailing_whitespace = true +insert_final_newline = true +end_of_line = lf +charset = utf-8 + +[*.{c,h,cpp,hpp}] +indent_style = space +indent_size = 4 diff --git a/src/algo/adaptivewaterline.cpp b/src/algo/adaptivewaterline.cpp index 40767c97..42e37fa7 100644 --- a/src/algo/adaptivewaterline.cpp +++ b/src/algo/adaptivewaterline.cpp @@ -1,59 +1,56 @@ /* $Id$ - * + * * Copyright (c) 2010-2011 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #include #include - -#include +#include #ifdef _OPENMP - #include +#include #endif +#include "line.hpp" #include "millingcutter.hpp" +#include "path.hpp" #include "point.hpp" #include "triangle.hpp" -#include "line.hpp" -#include "path.hpp" #include "adaptivewaterline.hpp" -#include "weave.hpp" #include "fiberpushcutter.hpp" +#include "weave.hpp" - -namespace ocl -{ +namespace ocl { //******** ********************** */ AdaptiveWaterline::AdaptiveWaterline() { subOp.clear(); - subOp.push_back( new FiberPushCutter() ); - subOp.push_back( new FiberPushCutter() ); + subOp.push_back(new FiberPushCutter()); + subOp.push_back(new FiberPushCutter()); subOp[0]->setXDirection(); subOp[1]->setYDirection(); - nthreads=1; + nthreads = 1; #ifdef _OPENMP - nthreads = omp_get_num_procs(); + nthreads = omp_get_num_procs(); // omp_set_dynamic(0); // omp_set_nested(1); #endif @@ -80,151 +77,153 @@ void AdaptiveWaterline::run2() { } void AdaptiveWaterline::adaptive_sampling_run() { - minx = surf->bb.minpt.x - 2*cutter->getRadius(); - maxx = surf->bb.maxpt.x + 2*cutter->getRadius(); - miny = surf->bb.minpt.y - 2*cutter->getRadius(); - maxy = surf->bb.maxpt.y + 2*cutter->getRadius(); - Line* line = new Line( Point(minx,miny,zh) , Point(maxx,maxy,zh) ); - Span* linespan = new LineSpan(*line); - + minx = surf->bb.minpt.x - 2 * cutter->getRadius(); + maxx = surf->bb.maxpt.x + 2 * cutter->getRadius(); + miny = surf->bb.minpt.y - 2 * cutter->getRadius(); + maxy = surf->bb.maxpt.y + 2 * cutter->getRadius(); + Line *line = new Line(Point(minx, miny, zh), Point(maxx, maxy, zh)); + Span *linespan = new LineSpan(*line); + #ifdef _WIN32 // OpenMP task not supported with the version 2 of VS2013 OpenMP - #pragma omp parallel sections - { - #pragma omp section // Replace OMP Task by Parallel sections - { // first child +#pragma omp parallel sections + { +#pragma omp section // Replace OMP Task by Parallel sections + { // first child #else #pragma omp parallel - { + { #pragma omp single nowait - { // initial root task + { // initial root task #pragma omp task - { // first child task + { // first child task #endif // _WIN32 - xfibers.clear(); - Point xstart_p1 = Point(minx, linespan->getPoint(0.0).y, zh); - Point xstart_p2 = Point(maxx, linespan->getPoint(0.0).y, zh); - Point xstop_p1 = Point(minx, linespan->getPoint(1.0).y, zh); - Point xstop_p2 = Point(maxx, linespan->getPoint(1.0).y, zh); - Fiber xstart_f = Fiber(xstart_p1, xstart_p2); - Fiber xstop_f = Fiber(xstop_p1, xstop_p2); - subOp[0]->run(xstart_f); - subOp[0]->run(xstop_f); - xfibers.push_back(xstart_f); - // std::cout << " XFiber adaptive sample \n"; - xfiber_adaptive_sample(linespan, 0.0, 1.0, xstart_f, xstop_f); + xfibers.clear(); + Point xstart_p1 = Point(minx, linespan->getPoint(0.0).y, zh); + Point xstart_p2 = Point(maxx, linespan->getPoint(0.0).y, zh); + Point xstop_p1 = Point(minx, linespan->getPoint(1.0).y, zh); + Point xstop_p2 = Point(maxx, linespan->getPoint(1.0).y, zh); + Fiber xstart_f = Fiber(xstart_p1, xstart_p2); + Fiber xstop_f = Fiber(xstop_p1, xstop_p2); + subOp[0]->run(xstart_f); + subOp[0]->run(xstop_f); + xfibers.push_back(xstart_f); + // std::cout << " XFiber adaptive sample \n"; + xfiber_adaptive_sample(linespan, 0.0, 1.0, xstart_f, xstop_f); #ifdef _WIN32 // OpenMP task not supported with the version 2 of VS2013 OpenMP - } - #pragma omp section - { // second child + } +#pragma omp section + {// second child #else - } -# pragma omp task - { // second child task + } +#pragma omp task + { // second child task #endif // _WIN32 - yfibers.clear(); - Point ystart_p1 = Point(linespan->getPoint(0.0).x, miny, zh); - Point ystart_p2 = Point(linespan->getPoint(0.0).x, maxy, zh); - Point ystop_p1 = Point(linespan->getPoint(1.0).x, miny, zh); - Point ystop_p2 = Point(linespan->getPoint(1.0).x, maxy, zh); - Fiber ystart_f = Fiber(ystart_p1, ystart_p2); - Fiber ystop_f = Fiber(ystop_p1, ystop_p2); - subOp[1]->run(ystart_f); - subOp[1]->run(ystop_f); - yfibers.push_back(ystart_f); - // std::cout << " YFiber adaptive sample \n"; - yfiber_adaptive_sample(linespan, 0.0, 1.0, ystart_f, ystop_f); + yfibers.clear(); + Point ystart_p1 = Point(linespan->getPoint(0.0).x, miny, zh); + Point ystart_p2 = Point(linespan->getPoint(0.0).x, maxy, zh); + Point ystop_p1 = Point(linespan->getPoint(1.0).x, miny, zh); + Point ystop_p2 = Point(linespan->getPoint(1.0).x, maxy, zh); + Fiber ystart_f = Fiber(ystart_p1, ystart_p2); + Fiber ystop_f = Fiber(ystop_p1, ystop_p2); + subOp[1]->run(ystart_f); + subOp[1]->run(ystop_f); + yfibers.push_back(ystart_f); + // std::cout << " YFiber adaptive sample \n"; + yfiber_adaptive_sample(linespan, 0.0, 1.0, ystart_f, ystop_f); #ifdef _WIN32 // OpenMP task not supported with the version 2 of VS2013 OpenMP - } - } // end omp parallel + } +} // end omp parallel #else } } } // end omp parallel #endif // _WIN32 - delete line; - delete linespan; - -} - - -void AdaptiveWaterline::xfiber_adaptive_sample(const Span* span, double start_t, double stop_t, Fiber start_f, Fiber stop_f) { - const double mid_t = start_t + (stop_t-start_t)/2.0; // mid point sample - assert( mid_t > start_t ); assert( mid_t < stop_t ); - //std::cout << "xfiber sample= ( " << start_t << " , " << stop_t << " ) \n"; - Point mid_p1 = Point( minx, span->getPoint( mid_t ).y, zh ); - Point mid_p2 = Point( maxx, span->getPoint( mid_t ).y, zh ); - Fiber mid_f = Fiber( mid_p1, mid_p2 ); - subOp[0]->run( mid_f ); - double fw_step = fabs( start_f.p1.y - stop_f.p1.y ) ; - if ( fw_step > sampling ) { // above minimum step-forward, need to sample more - xfiber_adaptive_sample( span, start_t, mid_t , start_f, mid_f ); - xfiber_adaptive_sample( span, mid_t , stop_t, mid_f , stop_f ); - } else if ( !flat(start_f,mid_f,stop_f) ) { +delete line; +delete linespan; + +} // namespace ocl + +void AdaptiveWaterline::xfiber_adaptive_sample(const Span *span, double start_t, double stop_t, Fiber start_f, + Fiber stop_f) { + const double mid_t = start_t + (stop_t - start_t) / 2.0; // mid point sample + assert(mid_t > start_t); + assert(mid_t < stop_t); + // std::cout << "xfiber sample= ( " << start_t << " , " << stop_t << " ) \n"; + Point mid_p1 = Point(minx, span->getPoint(mid_t).y, zh); + Point mid_p2 = Point(maxx, span->getPoint(mid_t).y, zh); + Fiber mid_f = Fiber(mid_p1, mid_p2); + subOp[0]->run(mid_f); + double fw_step = fabs(start_f.p1.y - stop_f.p1.y); + if (fw_step > sampling) { // above minimum step-forward, need to sample more + xfiber_adaptive_sample(span, start_t, mid_t, start_f, mid_f); + xfiber_adaptive_sample(span, mid_t, stop_t, mid_f, stop_f); + } else if (!flat(start_f, mid_f, stop_f)) { if (fw_step > min_sampling) { // not a flat segment, and we have not reached maximum sampling - xfiber_adaptive_sample( span, start_t, mid_t , start_f, mid_f ); - xfiber_adaptive_sample( span, mid_t , stop_t, mid_f , stop_f ); + xfiber_adaptive_sample(span, start_t, mid_t, start_f, mid_f); + xfiber_adaptive_sample(span, mid_t, stop_t, mid_f, stop_f); } } else { xfibers.push_back(stop_f); - } + } } -void AdaptiveWaterline::yfiber_adaptive_sample(const Span* span, double start_t, double stop_t, Fiber start_f, Fiber stop_f) { - const double mid_t = start_t + (stop_t-start_t)/2.0; // mid point sample - assert( mid_t > start_t ); assert( mid_t < stop_t ); - //std::cout << "yfiber sample= ( " << start_t << " , " << stop_t << " ) \n"; - Point mid_p1 = Point( span->getPoint( mid_t ).x, miny, zh ); - Point mid_p2 = Point( span->getPoint( mid_t ).x, maxy, zh ); - Fiber mid_f = Fiber( mid_p1, mid_p2 ); - subOp[1]->run( mid_f ); - double fw_step = fabs( start_f.p1.x - stop_f.p1.x ) ; - if ( fw_step > sampling ) { // above minimum step-forward, need to sample more - yfiber_adaptive_sample( span, start_t, mid_t , start_f, mid_f ); - yfiber_adaptive_sample( span, mid_t , stop_t, mid_f , stop_f ); - } else if ( !flat(start_f,mid_f,stop_f) ) { +void AdaptiveWaterline::yfiber_adaptive_sample(const Span *span, double start_t, double stop_t, Fiber start_f, + Fiber stop_f) { + const double mid_t = start_t + (stop_t - start_t) / 2.0; // mid point sample + assert(mid_t > start_t); + assert(mid_t < stop_t); + // std::cout << "yfiber sample= ( " << start_t << " , " << stop_t << " ) \n"; + Point mid_p1 = Point(span->getPoint(mid_t).x, miny, zh); + Point mid_p2 = Point(span->getPoint(mid_t).x, maxy, zh); + Fiber mid_f = Fiber(mid_p1, mid_p2); + subOp[1]->run(mid_f); + double fw_step = fabs(start_f.p1.x - stop_f.p1.x); + if (fw_step > sampling) { // above minimum step-forward, need to sample more + yfiber_adaptive_sample(span, start_t, mid_t, start_f, mid_f); + yfiber_adaptive_sample(span, mid_t, stop_t, mid_f, stop_f); + } else if (!flat(start_f, mid_f, stop_f)) { if (fw_step > min_sampling) { // not a flat segment, and we have not reached maximum sampling - yfiber_adaptive_sample( span, start_t, mid_t , start_f, mid_f ); - yfiber_adaptive_sample( span, mid_t , stop_t, mid_f , stop_f ); + yfiber_adaptive_sample(span, start_t, mid_t, start_f, mid_f); + yfiber_adaptive_sample(span, mid_t, stop_t, mid_f, stop_f); } } else { - yfibers.push_back(stop_f); + yfibers.push_back(stop_f); } } // flat predicate to determine when we subdivide -bool AdaptiveWaterline::flat( Fiber& start, Fiber& mid, Fiber& stop ) const { - if ( start.size() != stop.size() ) // start, mid, and stop need to have same size() +bool AdaptiveWaterline::flat(Fiber &start, Fiber &mid, Fiber &stop) const { + if (start.size() != stop.size()) // start, mid, and stop need to have same size() return false; - else if ( start.size() != mid.size() ) + else if (start.size() != mid.size()) return false; - else if ( mid.size() != stop.size() ) + else if (mid.size() != stop.size()) return false; else { - if (!start.empty() ) { // all now have same size - assert( start.size() == stop.size() && start.size() == mid.size() ); - for (unsigned int n=0;ncosLimit); + double dotprod = v1.dot(v2); + return (dotprod > cosLimit); } -}// end namespace +} // namespace ocl // end file adaptivewaterline.cpp diff --git a/src/algo/adaptivewaterline.hpp b/src/algo/adaptivewaterline.hpp index e00042c0..8468350b 100644 --- a/src/algo/adaptivewaterline.hpp +++ b/src/algo/adaptivewaterline.hpp @@ -1,23 +1,23 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef ADAPTIVEWATERLINE_HPP #define ADAPTIVEWATERLINE_HPP @@ -28,65 +28,63 @@ #include -#include "waterline.hpp" #include "fiber.hpp" +#include "waterline.hpp" -namespace ocl -{ +namespace ocl { class Span; /// \brief a Waterline toolpath follows the shape of the model at a constant z-height in the xy-plane class AdaptiveWaterline : public Waterline { - public: - /// create an empty Waterline object - AdaptiveWaterline(); - virtual ~AdaptiveWaterline(); - /// set the minimum sampling interval - void setMinSampling(double s) {min_sampling=s;} - /// set the cosine limit for the flat() predicate - void setCosLimit(double lim) {cosLimit=lim;} - - /// run the Waterline algorithm. setSTL, setCutter, setSampling, and setZ must - /// be called before a call to run() - void run(); - void run2(); - - virtual void setSampling(double s) { - sampling=s; - min_sampling = sampling/10.0; // default to this when setMinSampling is not called - } - - - protected: - /// adaptive waterline algorithm - void adaptive_sampling_run(); - /// x-direction adaptive sampling - void xfiber_adaptive_sample(const Span* span, double start_t, double stop_t, Fiber start_f, Fiber stop_f); - /// y-direction adaptive sampling - void yfiber_adaptive_sample(const Span* span, double start_t, double stop_t, Fiber start_f, Fiber stop_f); - /// flatness predicate for fibers. Checks Fiber.size() and then calls flat() on cl-points - bool flat( Fiber& start, Fiber& mid, Fiber& stop ) const; - /// flatness predicate for cl-points. checks for angle metween start-mid-stop - bool flat(Point start_cl, Point mid_cl, Point stop_cl) const; + public: + /// create an empty Waterline object + AdaptiveWaterline(); + virtual ~AdaptiveWaterline(); + /// set the minimum sampling interval + void setMinSampling(double s) { min_sampling = s; } + /// set the cosine limit for the flat() predicate + void setCosLimit(double lim) { cosLimit = lim; } + + /// run the Waterline algorithm. setSTL, setCutter, setSampling, and setZ must + /// be called before a call to run() + void run(); + void run2(); + + virtual void setSampling(double s) { + sampling = s; + min_sampling = sampling / 10.0; // default to this when setMinSampling is not called + } + + protected: + /// adaptive waterline algorithm + void adaptive_sampling_run(); + /// x-direction adaptive sampling + void xfiber_adaptive_sample(const Span *span, double start_t, double stop_t, Fiber start_f, Fiber stop_f); + /// y-direction adaptive sampling + void yfiber_adaptive_sample(const Span *span, double start_t, double stop_t, Fiber start_f, Fiber stop_f); + /// flatness predicate for fibers. Checks Fiber.size() and then calls flat() on cl-points + bool flat(Fiber &start, Fiber &mid, Fiber &stop) const; + /// flatness predicate for cl-points. checks for angle metween start-mid-stop + bool flat(Point start_cl, Point mid_cl, Point stop_cl) const; // DATA - /// minimum x-coordinate - double minx; - /// maximum x-coordinate - double maxx; - /// minimum y-coordinate - double miny; - /// maximum y-coordinate - double maxy; - /// the minimum sampling interval when subdividing - double min_sampling; - /// the cosine limit value for cl-point flat(). In the constructor, cosLimit = 0.999 by default. - double cosLimit; + /// minimum x-coordinate + double minx; + /// maximum x-coordinate + double maxx; + /// minimum y-coordinate + double miny; + /// maximum y-coordinate + double maxy; + /// the minimum sampling interval when subdividing + double min_sampling; + /// the cosine limit value for cl-point flat(). In the constructor, cosLimit = 0.999 by default. + double cosLimit; }; -} // end namespace +} // namespace ocl #endif diff --git a/src/algo/batchpushcutter.cpp b/src/algo/batchpushcutter.cpp index e6b17026..f15c87ea 100644 --- a/src/algo/batchpushcutter.cpp +++ b/src/algo/batchpushcutter.cpp @@ -1,37 +1,36 @@ /* $Id$ - * + * * Copyright (c) 2010-2011 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #include -#ifdef _OPENMP - #include +#ifdef _OPENMP +#include #endif +#include "batchpushcutter.hpp" #include "millingcutter.hpp" #include "point.hpp" #include "triangle.hpp" -#include "batchpushcutter.hpp" -namespace ocl -{ +namespace ocl { //******** ********************** */ @@ -55,7 +54,7 @@ BatchPushCutter::~BatchPushCutter() { void BatchPushCutter::setSTL(const STLSurf &s) { surf = &s; // std::cout << "BPC::setSTL() Building kd-tree... bucketSize=" << bucketSize << ".."; - root->setBucketSize( bucketSize ); + root->setBucketSize(bucketSize); if (x_direction) root->setYZDimensions(); // we search for triangles in the XY plane, don't care about Z-coordinate else if (y_direction) @@ -69,24 +68,20 @@ void BatchPushCutter::setSTL(const STLSurf &s) { // std::cout << "done.\n"; } -void BatchPushCutter::appendFiber(Fiber& f) { - fibers->push_back(f); -} +void BatchPushCutter::appendFiber(Fiber &f) { fibers->push_back(f); } -void BatchPushCutter::reset() { - fibers->clear(); -} +void BatchPushCutter::reset() { fibers->clear(); } /// very simple batch push-cutter /// each fiber is tested against all triangles of surface void BatchPushCutter::pushCutter1() { - // std::cout << "BatchPushCutter1 with " << fibers->size() << + // std::cout << "BatchPushCutter1 with " << fibers->size() << // " fibers and " << surf->tris.size() << " triangles..." << std::endl; nCalls = 0; - BOOST_FOREACH(Fiber& f, *fibers) { - BOOST_FOREACH( const Triangle& t, surf->tris) {// test against all triangles in s + BOOST_FOREACH (Fiber &f, *fibers) { + BOOST_FOREACH (const Triangle &t, surf->tris) { // test against all triangles in s Interval i; - cutter->pushCutter(f,i,t); + cutter->pushCutter(f, i, t); f.addInterval(i); ++nCalls; } @@ -95,14 +90,14 @@ void BatchPushCutter::pushCutter1() { return; } -/// push-cutter which uses KDNode2 kd-tree search to find triangles +/// push-cutter which uses KDNode2 kd-tree search to find triangles /// overlapping with the cutter. void BatchPushCutter::pushCutter2() { - // std::cout << "BatchPushCutter2 with " << fibers->size() << + // std::cout << "BatchPushCutter2 with " << fibers->size() << // " fibers and " << surf->tris.size() << " triangles..." << std::endl; nCalls = 0; - std::list* overlap_triangles; - BOOST_FOREACH(Fiber& f, *fibers) { + std::list *overlap_triangles; + BOOST_FOREACH (Fiber &f, *fibers) { CLPoint cl; if (x_direction) { cl.x = 0; @@ -116,16 +111,16 @@ void BatchPushCutter::pushCutter2() { assert(0); } overlap_triangles = root->search_cutter_overlap(cutter, &cl); - assert( overlap_triangles->size() <= surf->size() ); // can't possibly find more triangles than in the STLSurf - BOOST_FOREACH( const Triangle& t, *overlap_triangles) { - //if ( bb->overlaps( t.bb ) ) { - Interval i; - cutter->pushCutter(f,i,t); - f.addInterval(i); - ++nCalls; + assert(overlap_triangles->size() <= surf->size()); // can't possibly find more triangles than in the STLSurf + BOOST_FOREACH (const Triangle &t, *overlap_triangles) { + // if ( bb->overlaps( t.bb ) ) { + Interval i; + cutter->pushCutter(f, i, t); + f.addInterval(i); + ++nCalls; //} } - delete( overlap_triangles ); + delete (overlap_triangles); } // std::cout << "BatchPushCutter2 done." << std::endl; return; @@ -134,58 +129,58 @@ void BatchPushCutter::pushCutter2() { /// use kd-tree search to find overlapping triangles /// use OpenMP for multi-threading void BatchPushCutter::pushCutter3() { - // std::cout << "BatchPushCutter3 with " << fibers->size() << + // std::cout << "BatchPushCutter3 with " << fibers->size() << // " fibers and " << surf->tris.size() << " triangles." << std::endl; // std::cout << " cutter = " << cutter->str() << "\n"; nCalls = 0; #ifdef _OPENMP omp_set_num_threads(nthreads); #endif - std::list::iterator it,it_end; // for looping over found triabgles - Interval* i; - std::list* tris; - std::vector& fiberr = *fibers; -#ifdef _WIN32 // OpenMP version 2 of VS2013 OpenMP need signed loop variable - int n; // loop variable - int Nmax = static_cast(fibers->size()); // the number of fibers to process + std::list::iterator it, it_end; // for looping over found triabgles + Interval *i; + std::list *tris; + std::vector &fiberr = *fibers; +#ifdef _WIN32 // OpenMP version 2 of VS2013 OpenMP need signed loop variable + int n; // loop variable + int Nmax = static_cast(fibers->size()); // the number of fibers to process #else - unsigned int n; // loop variable - unsigned int Nmax = fibers->size(); // the number of fibers to process + unsigned int n; // loop variable + unsigned int Nmax = fibers->size(); // the number of fibers to process #endif - unsigned int calls=0; - - #pragma omp parallel for schedule(dynamic) shared(calls, fiberr) private(n,i,tris,it,it_end) - //#pragma omp parallel for shared( calls, fiberr) private(n,i,tris,it,it_end) - for (n=0; nsearch_cutter_overlap(cutter, &cl); it_end = tris->end(); - for ( it=tris->begin() ; it!=it_end ; ++it) { // loop through the found overlapping triangles - //if ( bb->overlaps( it->bb ) ) { - // todo: optimization where method-calls are skipped if triangle bbox already in the fiber - i = new Interval(); - cutter->pushCutter(fiberr[n],*i,*it); - fiberr[n].addInterval(*i); - ++calls; - delete i; + for (it = tris->begin(); it != it_end; ++it) { // loop through the found overlapping triangles + // if ( bb->overlaps( it->bb ) ) { + // todo: optimization where method-calls are skipped if triangle bbox already in the fiber + i = new Interval(); + cutter->pushCutter(fiberr[n], *i, *it); + fiberr[n].addInterval(*i); + ++calls; + delete i; //} } - delete( tris ); + delete (tris); } // OpenMP parallel region ends here - + this->nCalls = calls; // std::cout << "\nBatchPushCutter3 done." << std::endl; return; } -}// end namespace +} // namespace ocl // end file batchpushcutter.cpp diff --git a/src/algo/batchpushcutter.hpp b/src/algo/batchpushcutter.hpp index 943bb0d7..554ad8bd 100644 --- a/src/algo/batchpushcutter.hpp +++ b/src/algo/batchpushcutter.hpp @@ -1,23 +1,23 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef BPC_H #define BPC_H @@ -26,13 +26,12 @@ #include #include -#include "point.hpp" #include "fiber.hpp" #include "kdtree.hpp" #include "operation.hpp" +#include "point.hpp" -namespace ocl -{ +namespace ocl { class STLSurf; class Triangle; @@ -44,45 +43,51 @@ class MillingCutter; /// When this runs the Fibers will be updated with the correct interval data. /// This is then used to build a weave and extract a waterline. class BatchPushCutter : public Operation { - public: - BatchPushCutter(); - virtual ~BatchPushCutter(); - - /// set the STL-surface and build kd-tree - void setSTL(const STLSurf& s); + public: + BatchPushCutter(); + virtual ~BatchPushCutter(); + + /// set the STL-surface and build kd-tree + void setSTL(const STLSurf &s); + + /// set this bpc to be x-direction + void setXDirection() { + x_direction = true; + y_direction = false; + } + /// set this bpc to be Y-direction + void setYDirection() { + x_direction = false; + y_direction = true; + } + /// append to list of Fibers to evaluate + void appendFiber(Fiber &f); + + /// run push-cutter + void run() { this->pushCutter3(); } + // void run() {this->pushCutter1();} + + std::vector *getFibers() const { return fibers; } + void reset(); + + protected: + /// 1st version of algorithm + void pushCutter1(); + /// 2nd version of algorithm + void pushCutter2(); + /// 3rd version of algorithm + void pushCutter3(); - /// set this bpc to be x-direction - void setXDirection() {x_direction=true;y_direction=false;} - /// set this bpc to be Y-direction - void setYDirection() {x_direction=false;y_direction=true;} - /// append to list of Fibers to evaluate - void appendFiber(Fiber& f); + /// pointer to list of Fibers + std::vector *fibers; - - /// run push-cutter - void run() {this->pushCutter3();} - //void run() {this->pushCutter1();} - - std::vector* getFibers() const {return fibers;} - void reset(); - protected: - /// 1st version of algorithm - void pushCutter1(); - /// 2nd version of algorithm - void pushCutter2(); - /// 3rd version of algorithm - void pushCutter3(); - - /// pointer to list of Fibers - std::vector* fibers; - // DATA - /// true if this we have only x-direction fibers - bool x_direction; - /// true if we have y-direction fibers - bool y_direction; + /// true if this we have only x-direction fibers + bool x_direction; + /// true if we have y-direction fibers + bool y_direction; }; -} // end namespace +} // namespace ocl #endif diff --git a/src/algo/clsurface.hpp b/src/algo/clsurface.hpp index 241f7f8d..0a2f87ed 100644 --- a/src/algo/clsurface.hpp +++ b/src/algo/clsurface.hpp @@ -1,81 +1,66 @@ /* $Id$ - * + * * Copyright (c) 2010-2011 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef CLSURFACE_H #define CLSURFACE_H -#include #include -#include #include +#include +#include -#include "point.hpp" #include "halfedgediagram.hpp" +#include "point.hpp" +namespace ocl { -namespace ocl -{ - -namespace clsurf -{ - - - - - -typedef boost::adjacency_list_traits::edge_descriptor CLSEdge; +namespace clsurf { +typedef boost::adjacency_list_traits::edge_descriptor + CLSEdge; -typedef boost::adjacency_list_traits::vertex_descriptor CLSVertex; -//typedef CLSGraph::Edge CLSEdge; -//typedef CLSGraph::Vertex CLSVertex; +typedef boost::adjacency_list_traits::vertex_descriptor + CLSVertex; +// typedef CLSGraph::Edge CLSEdge; +// typedef CLSGraph::Vertex CLSVertex; typedef unsigned int CLSFace; -//typedef hedi::HEDIGraph::Face CLSFace; +// typedef hedi::HEDIGraph::Face CLSFace; typedef std::vector CLSVertexVector; typedef std::vector CLSFaceVector; -typedef std::vector CLSEdgeVector; - +typedef std::vector CLSEdgeVector; struct CLSVertexProps { - CLSVertexProps() { - init(); - } + CLSVertexProps() { init(); } /// construct vertex at position p with type t - CLSVertexProps( Point p) { - position=p; + CLSVertexProps(Point p) { + position = p; init(); } void init() { index = count; count++; } -// HE data - Point position; ///< the position of the vertex - int index; ///< index of vertex + // HE data + Point position; ///< the position of the vertex + int index; ///< index of vertex static int count; ///< global vertex count }; @@ -84,42 +69,37 @@ int CLSVertexProps::count = 0; struct CLSEdgeProps { CLSEdgeProps() {} /// create edge with given next, twin, and face - CLSEdgeProps(CLSEdge n, CLSEdge t, CLSFace f) { + CLSEdgeProps(CLSEdge n, CLSEdge t, CLSFace f) { next = n; twin = t; face = f; } CLSEdge next; ///< the next edge, counterclockwise, from this edge CLSEdge twin; ///< the twin edge - CLSFace face; ///< the face to which this edge belongs + CLSFace face; ///< the face to which this edge belongs }; -/// properties of a face +/// properties of a face struct CLSFaceProps { /// create face with given edge, generator, and type CLSFaceProps() {} - CLSFaceProps( CLSEdge e ) { - edge = e; - } - - CLSFace idx; ///< face index - CLSEdge edge; ///< one edge that bounds this face + CLSFaceProps(CLSEdge e) { edge = e; } + CLSFace idx; ///< face index + CLSEdge edge; ///< one edge that bounds this face }; - // the cutter location surface graph -typedef hedi::HEDIGraph< boost::listS, // out-edge storage - boost::listS, // vertex set storage - boost::bidirectionalS, // bidirectional graph. - CLSVertexProps, // vertex properties - CLSEdgeProps, // edge properties - CLSFaceProps, // face properties - boost::no_property, // graph properties - boost::listS // edge storage - > CLSGraph; - - +typedef hedi::HEDIGraph + CLSGraph; /// \brief cutter location surface. /// @@ -141,156 +121,149 @@ typedef hedi::HEDIGraph< boost::listS, // out-edge storage /// http://www.graphics.rwth-aachen.de/uploads/media/bommes_07_VMV_01.pdf /// class CutterLocationSurface : public Operation { - public: - CutterLocationSurface() { - far=1.0; - init(); - } - /// create diagram with given far-radius and number of bins - CutterLocationSurface(double f) { - far=f; - init(); - } - virtual ~CutterLocationSurface() { - } - - void init() { - // initialize cl-surf - // - // b e1 a - // e2 e4 - // c e3 d - CLSVertex a = g.add_vertex(); // VertexProps( Point(far,far,0) ), g); - g[a].position = Point(far,far,0); - CLSVertex b = g.add_vertex(); // VertexProps( Point(-far,far,0) ), g); - g[b].position = Point(-far,far,0); - CLSVertex c = g.add_vertex(); // VertexProps( Point(-far,-far,0) ), g); - g[c].position = Point(-far,-far,0); - CLSVertex d = g.add_vertex(); // VertexProps( Point(far,-far,0) ), g); - g[c].position = Point(far,-far,0); - CLSFace f_outer= g.add_face( ); - CLSFace f_inner= g.add_face( ); - CLSEdge e1 = g.add_edge(a , b ); - CLSEdge e1t = g.add_edge(b , a ); - CLSEdge e2 = g.add_edge(b , c ); - CLSEdge e2t = g.add_edge(c , b ); - CLSEdge e3 = g.add_edge(c , d ); - CLSEdge e3t = g.add_edge(d , c ); - CLSEdge e4 = g.add_edge(d , a ); - CLSEdge e4t = g.add_edge(a , d ); - - g[f_inner].edge = e1; - g[f_outer].edge = e1t; - out_face = f_outer; - // twin edges - g.twin_edges(e1,e1t); - g.twin_edges(e2,e2t); - g.twin_edges(e3,e3t); - g.twin_edges(e4,e4t); - // inner face: - g[e1].face = f_inner; - g[e2].face = f_inner; - g[e3].face = f_inner; - g[e4].face = f_inner; - // outer face: - g[e1t].face = f_outer; - g[e2t].face = f_outer; - g[e3t].face = f_outer; - g[e4t].face = f_outer; - // next-pointers: - g[e1].next = e2; - g[e2].next = e3; - g[e3].next = e4; - g[e4].next = e1; - // outer next-pointers: - g[e1t].next = e4t; - g[e4t].next = e3t; - g[e3t].next = e2t; - g[e2t].next = e1t; - - subdivide(); - - } - - void subdivide() { - for( CLSFace f=0; f< g.num_faces() ; ++f ) { - // subdivide each face - if ( f!= out_face ) { - subdivide_face(f); - } - } - } - - void subdivide_face(CLSFace f) { - CLSEdgeVector f_edges = g.face_edges(f); - assert( f_edges.size() == 4 ); - CLSVertex center = g.add_vertex(); - BOOST_FOREACH( CLSEdge e, f_edges ) { - CLSVertex src = g.source(e); - CLSVertex trg = g.target(e); - // new vertex at mid-point of each edge - Point mid = 0.5*(g[src].position+g[trg].position); - g[center].position += 0.25*g[src].position; // average of four corners - CLSVertex v = g.add_vertex(); - g[v].position = mid; - g.insert_vertex_in_edge(v,e); // this also removes the old edges... - } - // now loop through edges again: - f_edges = g.face_edges(f); - assert( f_edges.size() == 8 ); - BOOST_FOREACH( CLSEdge e, f_edges ) { - std::cout << e << "\n"; + public: + CutterLocationSurface() { + far = 1.0; + init(); + } + /// create diagram with given far-radius and number of bins + CutterLocationSurface(double f) { + far = f; + init(); + } + virtual ~CutterLocationSurface() {} + + void init() { + // initialize cl-surf + // + // b e1 a + // e2 e4 + // c e3 d + CLSVertex a = g.add_vertex(); // VertexProps( Point(far,far,0) ), g); + g[a].position = Point(far, far, 0); + CLSVertex b = g.add_vertex(); // VertexProps( Point(-far,far,0) ), g); + g[b].position = Point(-far, far, 0); + CLSVertex c = g.add_vertex(); // VertexProps( Point(-far,-far,0) ), g); + g[c].position = Point(-far, -far, 0); + CLSVertex d = g.add_vertex(); // VertexProps( Point(far,-far,0) ), g); + g[c].position = Point(far, -far, 0); + CLSFace f_outer = g.add_face(); + CLSFace f_inner = g.add_face(); + CLSEdge e1 = g.add_edge(a, b); + CLSEdge e1t = g.add_edge(b, a); + CLSEdge e2 = g.add_edge(b, c); + CLSEdge e2t = g.add_edge(c, b); + CLSEdge e3 = g.add_edge(c, d); + CLSEdge e3t = g.add_edge(d, c); + CLSEdge e4 = g.add_edge(d, a); + CLSEdge e4t = g.add_edge(a, d); + + g[f_inner].edge = e1; + g[f_outer].edge = e1t; + out_face = f_outer; + // twin edges + g.twin_edges(e1, e1t); + g.twin_edges(e2, e2t); + g.twin_edges(e3, e3t); + g.twin_edges(e4, e4t); + // inner face: + g[e1].face = f_inner; + g[e2].face = f_inner; + g[e3].face = f_inner; + g[e4].face = f_inner; + // outer face: + g[e1t].face = f_outer; + g[e2t].face = f_outer; + g[e3t].face = f_outer; + g[e4t].face = f_outer; + // next-pointers: + g[e1].next = e2; + g[e2].next = e3; + g[e3].next = e4; + g[e4].next = e1; + // outer next-pointers: + g[e1t].next = e4t; + g[e4t].next = e3t; + g[e3t].next = e2t; + g[e2t].next = e1t; + + subdivide(); + } + + void subdivide() { + for (CLSFace f = 0; f < g.num_faces(); ++f) { + // subdivide each face + if (f != out_face) { + subdivide_face(f); } } - - virtual void run() { + } + + void subdivide_face(CLSFace f) { + CLSEdgeVector f_edges = g.face_edges(f); + assert(f_edges.size() == 4); + CLSVertex center = g.add_vertex(); + BOOST_FOREACH (CLSEdge e, f_edges) { + CLSVertex src = g.source(e); + CLSVertex trg = g.target(e); + // new vertex at mid-point of each edge + Point mid = 0.5 * (g[src].position + g[trg].position); + g[center].position += 0.25 * g[src].position; // average of four corners + CLSVertex v = g.add_vertex(); + g[v].position = mid; + g.insert_vertex_in_edge(v, e); // this also removes the old edges... } - void setMinSampling(double s) { - min_sampling=s; + // now loop through edges again: + f_edges = g.face_edges(f); + assert(f_edges.size() == 8); + BOOST_FOREACH (CLSEdge e, f_edges) { + std::cout << e << "\n"; } - + } + + virtual void run() {} + void setMinSampling(double s) { min_sampling = s; } + // PYTHON - boost::python::list getVertices() { - boost::python::list plist; - BOOST_FOREACH( CLSVertex v, g.vertices() ) { - plist.append( g[v].position ); - } - return plist; - } - - boost::python::list getEdges() { - boost::python::list edge_list; - BOOST_FOREACH( CLSEdge edge, g.edges() ) { // loop through each edge - boost::python::list point_list; // the endpoints of each edge - CLSVertex v1 = g.source( edge ); - CLSVertex v2 = g.target( edge ); - point_list.append( g[v1].position ); - point_list.append( g[v2].position ); - edge_list.append(point_list); - } - return edge_list; + boost::python::list getVertices() { + boost::python::list plist; + BOOST_FOREACH (CLSVertex v, g.vertices()) { + plist.append(g[v].position); } - - /// string repr - std::string str() const { - std::ostringstream o; - o << "CutterLocationSurface (nVerts="<< g.num_vertices() << " , nEdges="<< g.num_edges() <<"\n"; - return o.str(); + return plist; + } + + boost::python::list getEdges() { + boost::python::list edge_list; + BOOST_FOREACH (CLSEdge edge, g.edges()) { // loop through each edge + boost::python::list point_list; // the endpoints of each edge + CLSVertex v1 = g.source(edge); + CLSVertex v2 = g.target(edge); + point_list.append(g[v1].position); + point_list.append(g[v2].position); + edge_list.append(point_list); } + return edge_list; + } - protected: - + /// string repr + std::string str() const { + std::ostringstream o; + o << "CutterLocationSurface (nVerts=" << g.num_vertices() << " , nEdges=" << g.num_edges() << "\n"; + return o.str(); + } + + protected: // DATA - /// the half-edge diagram - CLSGraph g; - double min_sampling; - double far; - CLSFace out_face; + /// the half-edge diagram + CLSGraph g; + double min_sampling; + double far; + CLSFace out_face; }; +} // namespace clsurf -}// end clsurf namespace - -} // end ocl namespace +} // namespace ocl #endif // end clsurface.h diff --git a/src/algo/fiber.cpp b/src/algo/fiber.cpp index cb34bc9e..f8145642 100644 --- a/src/algo/fiber.cpp +++ b/src/algo/fiber.cpp @@ -1,70 +1,69 @@ /* $Id$ - * + * * Copyright (c) 2010-2011 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #include #include "fiber.hpp" -namespace ocl -{ +namespace ocl { Fiber::Fiber(const Point &p1in, const Point &p2in) { - p1=p1in; - p2=p2in; + p1 = p1in; + p2 = p2in; calcDir(); } void Fiber::calcDir() { dir = p2 - p1; - assert( dir.z == 0.0 ); + assert(dir.z == 0.0); dir.normalize(); } -bool Fiber::contains(Interval& i) const { - BOOST_FOREACH( Interval fi, ints) { - if ( i.inside( fi ) ) +bool Fiber::contains(Interval &i) const { + BOOST_FOREACH (Interval fi, ints) { + if (i.inside(fi)) return true; } return false; } -bool Fiber::missing(Interval& i) const { +bool Fiber::missing(Interval &i) const { bool result = true; - BOOST_FOREACH( Interval fi, ints) { - if ( !i.outside( fi ) ) // all existing ints must be non-overlapping - result = false; + BOOST_FOREACH (Interval fi, ints) { + if (!i.outside(fi)) // all existing ints must be non-overlapping + result = false; } return result; } -void Fiber::addInterval(Interval& i) { +void Fiber::addInterval(Interval &i) { if (i.empty()) return; // do nothing. - + if (ints.empty()) { // empty fiber case - ints.push_back(i); + ints.push_back(i); return; - } else if ( this->contains(i) ) { // if fiber already contains i - return; // do nothing - } else if ( this->missing(i) ) { // if fiber doesn't contain i + } else if (this->contains(i)) { // if fiber already contains i + return; // do nothing + } else if (this->missing(i)) { // if fiber doesn't contain i ints.push_back(i); return; } else { @@ -72,51 +71,51 @@ void Fiber::addInterval(Interval& i) { std::vector::iterator itr; itr = ints.begin(); std::vector overlaps; - while (itr!=ints.end()) { // loop through all intervals - if ( ! (itr->outside( i )) ) { + while (itr != ints.end()) { // loop through all intervals + if (!(itr->outside(i))) { overlaps.push_back(*itr); // add overlaps here - itr = ints.erase(itr); // erase overlaps from ints + itr = ints.erase(itr); // erase overlaps from ints } else { ++itr; } } overlaps.push_back(i); // now build a new interval from i and the overlaps - Interval sumint; - BOOST_FOREACH(Interval intr, overlaps) { - sumint.updateLower( intr.lower, intr.lower_cc ); - sumint.updateUpper( intr.upper, intr.upper_cc ); + Interval sumint; + BOOST_FOREACH (Interval intr, overlaps) { + sumint.updateLower(intr.lower, intr.lower_cc); + sumint.updateUpper(intr.upper, intr.upper_cc); } ints.push_back(sumint); // add the sum-interval to ints return; } } -double Fiber::tval(Point& p) const { +double Fiber::tval(Point &p) const { // fiber is f = p1 + t * (p2-p1) // t = (f-p1).dot(p2-p1) / (p2-p1).dot(p2-p1) - return (p-p1).dot(p2-p1) / (p2-p1).dot(p2-p1); + return (p - p1).dot(p2 - p1) / (p2 - p1).dot(p2 - p1); } Point Fiber::point(double t) const { - Point p = p1 + t*(p2-p1); + Point p = p1 + t * (p2 - p1); return p; } void Fiber::printInts() const { - int n=0; - BOOST_FOREACH( Interval i, ints) { - std::cout << n << ": [ " << i.lower << " , " << i.upper << " ]" << "\n"; + int n = 0; + BOOST_FOREACH (Interval i, ints) { + std::cout << n << ": [ " << i.lower << " , " << i.upper << " ]" + << "\n"; ++n; } } -std::ostream& operator<<(std::ostream &stream, const Fiber& f) { - stream << " fiber dir=" << f.dir << " and " << f.ints.size() << " intervals\n"; - stream << " fiber.p1=" << f.p1 << " fiber.p2 " << f.p2 ; - return stream; +std::ostream &operator<<(std::ostream &stream, const Fiber &f) { + stream << " fiber dir=" << f.dir << " and " << f.ints.size() << " intervals\n"; + stream << " fiber.p1=" << f.p1 << " fiber.p2 " << f.p2; + return stream; } - -} // end namespace +} // namespace ocl // end file fiber.cpp diff --git a/src/algo/fiber.hpp b/src/algo/fiber.hpp index bdcc24c7..4156a9d3 100644 --- a/src/algo/fiber.hpp +++ b/src/algo/fiber.hpp @@ -1,90 +1,85 @@ /* $Id$ - * + * * Copyright (c) 2010-2011 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef FIBER_HPP #define FIBER_HPP #include -#include "point.hpp" #include "interval.hpp" +#include "point.hpp" -namespace ocl -{ +namespace ocl { /// a fiber is an infinite line in space along which the cutter can be pushed /// into contact with a triangle. A Weave is built from many X-fibers and Y-fibers. /// might be called a Dexel also in some papers/textbooks. class Fiber { - public: - Fiber() {ints.clear();} - /// create a Fiber between points p1 and p2 - Fiber(const Point &p1, const Point &p2); - virtual ~Fiber() {} - /// add an interval to this Fiber - void addInterval(Interval& i); - /// return true if Fiber already has interval i in it - bool contains(Interval& i) const; - /// return true if Interval i is completely missing (no overlaps) from Fiber - bool missing(Interval& i) const; - - /// t-value corresponding to Point p - double tval(Point& p) const; - /// Point corresponding to t-value - Point point(double t) const; - /// print the intervals - void printInts() const; - /// return true if the Fiber contains no intervals - bool empty() const {return ints.empty();} - /// return number of intervals - unsigned int size() const {return static_cast(ints.size());} - - /// return the upper cl-point of interval n - Point upperCLPoint(unsigned int n) const { - return point(ints[n].upper); - } - /// return the lower cl-point of interval n - Point lowerCLPoint(unsigned int n) const { - return point(ints[n].lower); - } - - /// string repr - friend std::ostream& operator<<(std::ostream &stream, const Fiber &f); - - bool operator==(const Fiber& other ) const { - if( (this->p1 == other.p1) && (this->p2 == other.p2) ) - return true; - else - return false; - } + public: + Fiber() { ints.clear(); } + /// create a Fiber between points p1 and p2 + Fiber(const Point &p1, const Point &p2); + virtual ~Fiber() {} + /// add an interval to this Fiber + void addInterval(Interval &i); + /// return true if Fiber already has interval i in it + bool contains(Interval &i) const; + /// return true if Interval i is completely missing (no overlaps) from Fiber + bool missing(Interval &i) const; + + /// t-value corresponding to Point p + double tval(Point &p) const; + /// Point corresponding to t-value + Point point(double t) const; + /// print the intervals + void printInts() const; + /// return true if the Fiber contains no intervals + bool empty() const { return ints.empty(); } + /// return number of intervals + unsigned int size() const { return static_cast(ints.size()); } + + /// return the upper cl-point of interval n + Point upperCLPoint(unsigned int n) const { return point(ints[n].upper); } + /// return the lower cl-point of interval n + Point lowerCLPoint(unsigned int n) const { return point(ints[n].lower); } + + /// string repr + friend std::ostream &operator<<(std::ostream &stream, const Fiber &f); + + bool operator==(const Fiber &other) const { + if ((this->p1 == other.p1) && (this->p2 == other.p2)) + return true; + else + return false; + } // DATA - Point p1; ///< start point - Point p2; ///< end point - Point dir; ///< direction vector (normalized) - std::vector ints; ///< the intervals in this Fiber - protected: - /// set the direction(tangent) vector - void calcDir(); + Point p1; ///< start point + Point p2; ///< end point + Point dir; ///< direction vector (normalized) + std::vector ints; ///< the intervals in this Fiber + protected: + /// set the direction(tangent) vector + void calcDir(); }; -} // end namespace +} // namespace ocl #endif // end file fiber.h diff --git a/src/algo/fiberpushcutter.cpp b/src/algo/fiberpushcutter.cpp index 3665859c..1f5a4bb6 100644 --- a/src/algo/fiberpushcutter.cpp +++ b/src/algo/fiberpushcutter.cpp @@ -1,37 +1,36 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #include -#ifdef _OPENMP - #include +#ifdef _OPENMP +#include #endif +#include "fiberpushcutter.hpp" #include "millingcutter.hpp" #include "point.hpp" #include "triangle.hpp" -#include "fiberpushcutter.hpp" -namespace ocl -{ +namespace ocl { //******** ********************** */ @@ -46,16 +45,14 @@ FiberPushCutter::FiberPushCutter() { root = new KDTree(); } -FiberPushCutter::~FiberPushCutter() { - delete root; -} +FiberPushCutter::~FiberPushCutter() { delete root; } void FiberPushCutter::setSTL(const STLSurf &s) { surf = &s; // std::cout << "BPC::setSTL() Building kd-tree... bucketSize=" << bucketSize << ".."; - root->setBucketSize( bucketSize ); + root->setBucketSize(bucketSize); if (x_direction) - root->setYZDimensions(); + root->setYZDimensions(); else if (y_direction) root->setXZDimensions(); else { @@ -67,41 +64,41 @@ void FiberPushCutter::setSTL(const STLSurf &s) { // std::cout << " done.\n"; } -void FiberPushCutter::pushCutter1(Fiber& f) { +void FiberPushCutter::pushCutter1(Fiber &f) { nCalls = 0; - BOOST_FOREACH( const Triangle& t, surf->tris) {// test against all triangles in s + BOOST_FOREACH (const Triangle &t, surf->tris) { // test against all triangles in s Interval i; - cutter->pushCutter(f,i,t); + cutter->pushCutter(f, i, t); f.addInterval(i); ++nCalls; } } -void FiberPushCutter::pushCutter2(Fiber& f) { - std::list::iterator it,it_end; // for looping over found triangles - Interval* i; - std::list* tris; +void FiberPushCutter::pushCutter2(Fiber &f) { + std::list::iterator it, it_end; // for looping over found triangles + Interval *i; + std::list *tris; CLPoint cl; - if ( x_direction ) { - cl.x=0; - cl.y=f.p1.y; - cl.z=f.p1.z; - } else if (y_direction ) { - cl.x=f.p1.x; - cl.y=0; - cl.z=f.p1.z; + if (x_direction) { + cl.x = 0; + cl.y = f.p1.y; + cl.z = f.p1.z; + } else if (y_direction) { + cl.x = f.p1.x; + cl.y = 0; + cl.z = f.p1.z; } tris = root->search_cutter_overlap(cutter, &cl); it_end = tris->end(); - for ( it=tris->begin() ; it!=it_end ; ++it) { - i = new Interval(); - cutter->pushCutter(f,*i,*it); - f.addInterval(*i); - ++nCalls; - delete i; + for (it = tris->begin(); it != it_end; ++it) { + i = new Interval(); + cutter->pushCutter(f, *i, *it); + f.addInterval(*i); + ++nCalls; + delete i; } - delete( tris ); + delete (tris); } -}// end namespace +} // namespace ocl // end file fiberpushcutter.cpp diff --git a/src/algo/fiberpushcutter.hpp b/src/algo/fiberpushcutter.hpp index ed51db82..ffd8e42d 100644 --- a/src/algo/fiberpushcutter.hpp +++ b/src/algo/fiberpushcutter.hpp @@ -1,23 +1,23 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef FIBERPUSHCUTTER_H #define FIBERPUSHCUTTER_H @@ -26,46 +26,50 @@ #include #include -#include "point.hpp" #include "fiber.hpp" #include "operation.hpp" +#include "point.hpp" -namespace ocl -{ - +namespace ocl { /// /// \brief run push-cutter on a single input fiber class FiberPushCutter : public Operation { - public: - FiberPushCutter(); - virtual ~FiberPushCutter(); - - /// set the STL-surface and build kd-tree - void setSTL(const STLSurf& s); + public: + FiberPushCutter(); + virtual ~FiberPushCutter(); + + /// set the STL-surface and build kd-tree + void setSTL(const STLSurf &s); + + /// set this bpc to be x-direction + void setXDirection() { + x_direction = true; + y_direction = false; + } + /// set this bpc to be Y-direction + void setYDirection() { + x_direction = false; + y_direction = true; + } + /// run() is an error. + void run() { assert(0); } + void run(Fiber &f) { pushCutter2(f); } + + protected: + /// input fiber is tested against all triangles of surface + void pushCutter1(Fiber &f); + /// use kd-tree search to find overlapping triangles + void pushCutter2(Fiber &f); - /// set this bpc to be x-direction - void setXDirection() {x_direction=true;y_direction=false;} - /// set this bpc to be Y-direction - void setYDirection() {x_direction=false;y_direction=true;} - /// run() is an error. - void run() {assert(0);} - void run(Fiber& f) {pushCutter2(f);} - - protected: - /// input fiber is tested against all triangles of surface - void pushCutter1(Fiber& f); - /// use kd-tree search to find overlapping triangles - void pushCutter2(Fiber& f); - // DATA - /// true if this we have only x-direction fibers - bool x_direction; - /// true if we have y-direction fibers - bool y_direction; + /// true if this we have only x-direction fibers + bool x_direction; + /// true if we have y-direction fibers + bool y_direction; }; -} // end namespace +} // namespace ocl #endif diff --git a/src/algo/interval.cpp b/src/algo/interval.cpp index 3cea20f1..294ea9f4 100644 --- a/src/algo/interval.cpp +++ b/src/algo/interval.cpp @@ -1,23 +1,23 @@ /* $Id$ - * + * * Copyright (c) 2010-2011 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #include #include @@ -25,93 +25,93 @@ #include "interval.hpp" -namespace ocl -{ +namespace ocl { Interval::Interval() { lower = 0.0; upper = 0.0; lower_cc = CCPoint(); upper_cc = CCPoint(); - in_weave=false; + in_weave = false; } Interval::Interval(const double l, const double u) { - assert( l <= u ); + assert(l <= u); lower = l; upper = u; - in_weave=false; + in_weave = false; } -void Interval::update(const double t, CCPoint& p) { - this->updateUpper(t,p); - this->updateLower(t,p); +void Interval::update(const double t, CCPoint &p) { + this->updateUpper(t, p); + this->updateLower(t, p); } -bool Interval::update_ifCCinEdgeAndTrue( double t_cl, CCPoint& cc_tmp, const Point& p1, const Point& p2, bool condition) { - //if ( cc_tmp.isInsidePoints(p1,p2) && condition ) { - if ( cc_tmp.isInside(p1,p2) && condition ) { - update( t_cl , cc_tmp ); // both updateUpper(t,p) and updateLower(t,p) - return true; +bool Interval::update_ifCCinEdgeAndTrue(double t_cl, CCPoint &cc_tmp, const Point &p1, const Point &p2, + bool condition) { + // if ( cc_tmp.isInsidePoints(p1,p2) && condition ) { + if (cc_tmp.isInside(p1, p2) && condition) { + update(t_cl, cc_tmp); // both updateUpper(t,p) and updateLower(t,p) + return true; } else { return false; } } -void Interval::updateUpper(const double t, CCPoint& p) { +void Interval::updateUpper(const double t, CCPoint &p) { if (upper_cc.type == NONE) { upper = t; lower = t; - CCPoint* tmp = new CCPoint(p); + CCPoint *tmp = new CCPoint(p); upper_cc = *tmp; lower_cc = *tmp; delete tmp; } - if ( t > upper ) { + if (t > upper) { upper = t; - CCPoint* tmp = new CCPoint(p); + CCPoint *tmp = new CCPoint(p); upper_cc = *tmp; delete tmp; - } + } } -void Interval::updateLower(const double t, CCPoint& p) { +void Interval::updateLower(const double t, CCPoint &p) { if (lower_cc.type == NONE) { lower = t; upper = t; - CCPoint* tmp = new CCPoint(p); + CCPoint *tmp = new CCPoint(p); lower_cc = *tmp; upper_cc = *tmp; delete tmp; } - if ( t < lower ) { - lower = t; - CCPoint* tmp = new CCPoint(p); + if (t < lower) { + lower = t; + CCPoint *tmp = new CCPoint(p); lower_cc = *tmp; delete tmp; } } // return true if *this is completely non-overlapping, or outside of i. -bool Interval::outside(const Interval& i) const { - if ( this->lower > i.upper ) +bool Interval::outside(const Interval &i) const { + if (this->lower > i.upper) return true; - else if ( this->upper < i.lower ) + else if (this->upper < i.lower) return true; else return false; } // return true if *this is contained within i -bool Interval::inside(const Interval& i) const { - if ( (this->lower > i.lower) && (this->upper < i.upper) ) +bool Interval::inside(const Interval &i) const { + if ((this->lower > i.lower) && (this->upper < i.upper)) return true; else return false; } bool Interval::empty() const { - if ( lower==0.0 && upper==0.0 ) + if (lower == 0.0 && upper == 0.0) return true; else return false; @@ -119,9 +119,9 @@ bool Interval::empty() const { std::string Interval::str() const { std::ostringstream o; - o << "I ["<< lower <<" , " << upper << " ]"; + o << "I [" << lower << " , " << upper << " ]"; return o.str(); } -} // end namespace +} // namespace ocl // end file interval.cpp diff --git a/src/algo/interval.hpp b/src/algo/interval.hpp index ef4acfc3..1f8131ad 100644 --- a/src/algo/interval.hpp +++ b/src/algo/interval.hpp @@ -1,31 +1,31 @@ /* $Id$ - * + * * Copyright (c) 2010-2011 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef INTERVAL_HPP #define INTERVAL_HPP #include -//#include +// #include #include "ccpoint.hpp" -//#include "weave_typedef.hpp" +// #include "weave_typedef.hpp" #include "halfedgediagram.hpp" namespace ocl { @@ -35,64 +35,59 @@ class Fiber; /// interval for use by fiber and weave /// a parameter interval [upper, lower] class Interval { - public: - Interval(); - /// create and interval [l,u] (is this ever called??) - Interval(const double l, const double u); - virtual ~Interval() {}; - - /// update upper with t, and corresponding cc-point p - void updateUpper(const double t, CCPoint& p); - /// update lower with t, and corresponding cc-point p - void updateLower(const double t, CCPoint& p); - /// call both updateUpper() and updateLower() with the given (t,p) pair - void update(const double t, CCPoint& p); - /// update interval with t_cl and cc_tmp if cc_tmp is in the p1-p2 edge and condition==true - bool update_ifCCinEdgeAndTrue( double t_cl, CCPoint& cc_tmp, const Point& p1, const Point& p2, bool condition); - - /// return true if Interval i is outside *this - bool outside(const Interval& i) const; - /// return true if Interval i is inside *this - bool inside(const Interval& i) const; - /// return true if the interval is empty - bool empty() const; - /// string repr - std::string str() const; - - - CCPoint upper_cc; ///< cutter contact points at upper and lower are stored in upper_cc and lower_cc - CCPoint lower_cc; ///< cutter contact point corresponding to lower - double upper; ///< the upper t-value - double lower; ///< the lower t-value - bool in_weave; ///< flag for use by Weave::build() - std::set::iterator> intersections_fibers; ///< fibers - - /// intersections with other intervals are stored in this set of - /// VertexPairs of type std::pair - - typedef boost::adjacency_list_traits::vertex_descriptor WeaveVertex; - typedef std::pair< WeaveVertex, double > VertexPair; + public: + Interval(); + /// create and interval [l,u] (is this ever called??) + Interval(const double l, const double u); + virtual ~Interval(){}; - /// compare based on pair.second, the coordinate of the intersection - struct VertexPairCompare { - /// comparison operator - bool operator() (const VertexPair& lhs, const VertexPair& rhs) const - { return lhs.second < rhs.second ;} - }; + /// update upper with t, and corresponding cc-point p + void updateUpper(const double t, CCPoint &p); + /// update lower with t, and corresponding cc-point p + void updateLower(const double t, CCPoint &p); + /// call both updateUpper() and updateLower() with the given (t,p) pair + void update(const double t, CCPoint &p); + /// update interval with t_cl and cc_tmp if cc_tmp is in the p1-p2 edge and condition==true + bool update_ifCCinEdgeAndTrue(double t_cl, CCPoint &cc_tmp, const Point &p1, const Point &p2, bool condition); - /// intersections stored in this set (for rapid finding of neighbors etc) - typedef std::set< VertexPair, VertexPairCompare > VertexIntersectionSet; - - // this is the same type as ocl::weave::VertexPairIterator, but redefined here anywhere - typedef VertexIntersectionSet::iterator VertexPairIterator; + /// return true if Interval i is outside *this + bool outside(const Interval &i) const; + /// return true if Interval i is inside *this + bool inside(const Interval &i) const; + /// return true if the interval is empty + bool empty() const; + /// string repr + std::string str() const; - - VertexIntersectionSet intersections2; + CCPoint upper_cc; ///< cutter contact points at upper and lower are stored in upper_cc and lower_cc + CCPoint lower_cc; ///< cutter contact point corresponding to lower + double upper; ///< the upper t-value + double lower; ///< the lower t-value + bool in_weave; ///< flag for use by Weave::build() + std::set::iterator> intersections_fibers; ///< fibers + + /// intersections with other intervals are stored in this set of + /// VertexPairs of type std::pair + + typedef boost::adjacency_list_traits::vertex_descriptor WeaveVertex; + typedef std::pair VertexPair; + + /// compare based on pair.second, the coordinate of the intersection + struct VertexPairCompare { + /// comparison operator + bool operator()(const VertexPair &lhs, const VertexPair &rhs) const { return lhs.second < rhs.second; } + }; + + /// intersections stored in this set (for rapid finding of neighbors etc) + typedef std::set VertexIntersectionSet; + + // this is the same type as ocl::weave::VertexPairIterator, but redefined here anywhere + typedef VertexIntersectionSet::iterator VertexPairIterator; + + VertexIntersectionSet intersections2; }; -} // end namespace +} // namespace ocl #endif // end file interval.hpp diff --git a/src/algo/operation.hpp b/src/algo/operation.hpp index 9d942662..aa7ffc2f 100644 --- a/src/algo/operation.hpp +++ b/src/algo/operation.hpp @@ -1,23 +1,23 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef OP_H #define OP_H @@ -26,12 +26,11 @@ #include #include -#include "point.hpp" #include "fiber.hpp" #include "kdtree.hpp" +#include "point.hpp" -namespace ocl -{ +namespace ocl { class STLSurf; class Triangle; @@ -41,102 +40,102 @@ class MillingCutter; /// /// base-class for cam algorithms class Operation { - public: - Operation() {} - virtual ~Operation() { - //std::cout << "~Operation()\n"; - } - /// set the STL-surface and build kd-tree - virtual void setSTL(const STLSurf& s) { - surf = &s; - BOOST_FOREACH(Operation* op, subOp) { - op->setSTL(s); - } + public: + Operation() {} + virtual ~Operation() { + // std::cout << "~Operation()\n"; + } + /// set the STL-surface and build kd-tree + virtual void setSTL(const STLSurf &s) { + surf = &s; + BOOST_FOREACH (Operation *op, subOp) { + op->setSTL(s); } - /// set the MillingCutter to use - virtual void setCutter(const MillingCutter* c) { - cutter = c; - BOOST_FOREACH(Operation* op, subOp) { - op->setCutter(cutter); - } + } + /// set the MillingCutter to use + virtual void setCutter(const MillingCutter *c) { + cutter = c; + BOOST_FOREACH (Operation *op, subOp) { + op->setCutter(cutter); } - /// set number of OpenMP threads. Defaults to OpenMP::omp_get_num_procs() - void setThreads(unsigned int n) { - nthreads = n; - BOOST_FOREACH(Operation* op, subOp) { - op->setThreads(nthreads); - } + } + /// set number of OpenMP threads. Defaults to OpenMP::omp_get_num_procs() + void setThreads(unsigned int n) { + nthreads = n; + BOOST_FOREACH (Operation *op, subOp) { + op->setThreads(nthreads); } - /// return number of OpenMP threads - int getThreads() const {return nthreads;} - /// return the kd-tree bucket-size - int getBucketSize() const {return bucketSize;} - /// set the kd-tree bucket-size - void setBucketSize(unsigned int s) { - bucketSize = s; - BOOST_FOREACH(Operation* op, subOp) { - op->setBucketSize(bucketSize); - } + } + /// return number of OpenMP threads + int getThreads() const { return nthreads; } + /// return the kd-tree bucket-size + int getBucketSize() const { return bucketSize; } + /// set the kd-tree bucket-size + void setBucketSize(unsigned int s) { + bucketSize = s; + BOOST_FOREACH (Operation *op, subOp) { + op->setBucketSize(bucketSize); } - /// return number of low-level calls - int getCalls() const {return nCalls;} - - /// set the sampling interval for this Operation and all sub-operations - virtual void setSampling(double s) { - sampling=s; - BOOST_FOREACH(Operation* op, subOp) { - op->setSampling(sampling); - } - } - /// return the sampling interval - virtual double getSampling() {return sampling;} - - /// run the algorithm - virtual void run() = 0; - /// run algorithm on a single input CLPoint - virtual void run(CLPoint& cl) {assert(0);} - /// run push-cutter type algorithm on input Fiber - virtual void run(Fiber& f) {assert(0);} - - virtual void reset() {} - - /// return CL-points - virtual std::vector getCLPoints() { - std::vector* clv = new std::vector(); - return *clv; + } + /// return number of low-level calls + int getCalls() const { return nCalls; } + + /// set the sampling interval for this Operation and all sub-operations + virtual void setSampling(double s) { + sampling = s; + BOOST_FOREACH (Operation *op, subOp) { + op->setSampling(sampling); } - virtual void clearCLPoints() {} - - /// add an input CLPoint to this Operation - virtual void appendPoint(CLPoint& p) {} - /// used by batchpushcutter - virtual void setXDirection() {} - /// used by batchpushcutter - virtual void setYDirection() {} - /// add a fiber input to a push-cutter type operation - virtual void appendFiber( Fiber& f ) {} - /// return the result of a push-cutter type operation - virtual std::vector* getFibers() const {return 0;} - - protected: - /// sampling interval - double sampling; - /// how many low-level calls were made - int nCalls; - /// size of bucket-node in KD-tree - unsigned int bucketSize; - /// the MillingCutter used - const MillingCutter* cutter; - /// the STLSurf which we test against. - const STLSurf* surf; - /// root of a kd-tree - KDTree* root; - /// number of threads to use - unsigned int nthreads; - /// sub-operations, if any, of this operation - std::vector subOp; + } + /// return the sampling interval + virtual double getSampling() { return sampling; } + + /// run the algorithm + virtual void run() = 0; + /// run algorithm on a single input CLPoint + virtual void run(CLPoint &cl) { assert(0); } + /// run push-cutter type algorithm on input Fiber + virtual void run(Fiber &f) { assert(0); } + + virtual void reset() {} + + /// return CL-points + virtual std::vector getCLPoints() { + std::vector *clv = new std::vector(); + return *clv; + } + virtual void clearCLPoints() {} + + /// add an input CLPoint to this Operation + virtual void appendPoint(CLPoint &p) {} + /// used by batchpushcutter + virtual void setXDirection() {} + /// used by batchpushcutter + virtual void setYDirection() {} + /// add a fiber input to a push-cutter type operation + virtual void appendFiber(Fiber &f) {} + /// return the result of a push-cutter type operation + virtual std::vector *getFibers() const { return 0; } + + protected: + /// sampling interval + double sampling; + /// how many low-level calls were made + int nCalls; + /// size of bucket-node in KD-tree + unsigned int bucketSize; + /// the MillingCutter used + const MillingCutter *cutter; + /// the STLSurf which we test against. + const STLSurf *surf; + /// root of a kd-tree + KDTree *root; + /// number of threads to use + unsigned int nthreads; + /// sub-operations, if any, of this operation + std::vector subOp; }; -} // end namespace +} // namespace ocl #endif // end operation.h diff --git a/src/algo/simple_weave.cpp b/src/algo/simple_weave.cpp index 89ff2d57..96194af7 100644 --- a/src/algo/simple_weave.cpp +++ b/src/algo/simple_weave.cpp @@ -1,23 +1,23 @@ /* $Id$ - * + * * Copyright (c) 2010-2011 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #include #include @@ -25,24 +25,23 @@ #include "simple_weave.hpp" -namespace ocl -{ +namespace ocl { -namespace weave -{ +namespace weave { -std::pair SimpleWeave::find_neighbor_vertices( VertexPair v_pair, Interval& ival) { - Interval::VertexPairIterator itr = ival.intersections2.lower_bound( v_pair ); // returns first that is not less than argument (equal or greater) - assert( itr != ival.intersections2.end() ); // we must find a lower_bound - Interval::VertexPairIterator v_above = itr; // lower_bound returns one beyond the give key, i.e. what we want +std::pair SimpleWeave::find_neighbor_vertices(VertexPair v_pair, Interval &ival) { + Interval::VertexPairIterator itr = + ival.intersections2.lower_bound(v_pair); // returns first that is not less than argument (equal or greater) + assert(itr != ival.intersections2.end()); // we must find a lower_bound + Interval::VertexPairIterator v_above = itr; // lower_bound returns one beyond the give key, i.e. what we want Interval::VertexPairIterator v_below = --itr; // this is the vertex below the give vertex - std::pair out; - out.first = v_above->first; // vertex above v (xu) + std::pair out; + out.first = v_above->first; // vertex above v (xu) out.second = v_below->first; // vertex below v (xl) - assert( out.first != out.second ); + assert(out.first != out.second); return out; } - + // from the list of fibers, build a graph // FIXME: the problem here is that from N x-fibers and N y-fibers // this builds a graph with roughly N*N vertices/edges. This consumes a lot of RAM even @@ -61,147 +60,147 @@ void SimpleWeave::build() { // xcl_lower <-> intp <-> xcl_upper // if this connects points that are already connected, then remove old edge and // provide this "via" connection - //int n_xfiber=0; + // int n_xfiber=0; // std::cout << " SimpleWeave::build()... \n"; - BOOST_FOREACH( Fiber& xf, xfibers) { - assert( !xf.empty() ); // no empty fibers please - BOOST_FOREACH( Interval& xi, xf.ints ) { - //std::cout << "x-fiber " << n_xfiber++ << "\n"; + BOOST_FOREACH (Fiber &xf, xfibers) { + assert(!xf.empty()); // no empty fibers please + BOOST_FOREACH (Interval &xi, xf.ints) { + // std::cout << "x-fiber " << n_xfiber++ << "\n"; double xmin = xf.point(xi.lower).x; double xmax = xf.point(xi.upper).x; - if ( (xmax-xmin) > 0) { - assert( !xi.in_weave ); // this is the first time the x-interval is added! - xi.in_weave = true; - // add the X interval end-points to the weave - Point p1( xf.point(xi.lower) ); - Vertex xv1 = add_cl_vertex( p1, xi, p1.x ); - Point p2( xf.point(xi.upper) ); - Vertex xv2 = add_cl_vertex( p2, xi, p2.x ); - Edge e1 = g.add_edge(xv1,xv2); - Edge e2 = g.add_edge(xv2,xv1); + if ((xmax - xmin) > 0) { + assert(!xi.in_weave); // this is the first time the x-interval is added! + xi.in_weave = true; + // add the X interval end-points to the weave + Point p1(xf.point(xi.lower)); + Vertex xv1 = add_cl_vertex(p1, xi, p1.x); + Point p2(xf.point(xi.upper)); + Vertex xv2 = add_cl_vertex(p2, xi, p2.x); + Edge e1 = g.add_edge(xv1, xv2); + Edge e2 = g.add_edge(xv2, xv1); + + // std::cout << " add_edge " << xv1 << "("<< p1.x<< ") - " << xv2 <<"("<< p2.x << ")\n"; + g[e1].next = e2; + g[e2].next = e1; + g[e1].prev = e2; + g[e2].prev = e1; + // int n_yfiber=0; + BOOST_FOREACH (Fiber &yf, yfibers) { // loop through all y-fibers for all x-intervals + if ((xmin < yf.p1.x) && (yf.p1.x < xmax)) { // potential intersection between y-fiber and x-interval + BOOST_FOREACH (Interval &yi, yf.ints) { + // std::cout << "y-fiber " << n_yfiber++ << "\n"; + double ymin = yf.point(yi.lower).y; + double ymax = yf.point(yi.upper).y; + if ((ymin < xf.p1.y) && (xf.p1.y < ymax)) { + // there is an actual intersection btw x-interval and y-interval + // X interval xi on fiber xf intersects with Y interval yi on fiber yf + // intersection is at ( yf.p1.x, xf.p1.y , xf.p1.z ) + if (!yi.in_weave) { // add y-interval endpoints to weave + Point yp1(yf.point(yi.lower)); + add_cl_vertex(yp1, yi, yp1.y); + Point yp2(yf.point(yi.upper)); + add_cl_vertex(yp2, yi, yp2.y); + yi.in_weave = true; + } + // 3) intersection point, of type INT + + Vertex v = g.null_vertex(); + + Point v_position(yf.p1.x, xf.p1.y, xf.p1.z); + // find neighbor to v + Vertex x_u, x_l; + + // std::cout << " fins neighbor to x= " << v_position.x << "\n"; + boost::tie(x_u, x_l) = find_neighbor_vertices(VertexPair(v, v_position.x), xi); + // std::cout << "found: x_u , x_l : " << x_u << " , " << x_l << "\n"; + Vertex y_u, y_l; + boost::tie(y_u, y_l) = find_neighbor_vertices(VertexPair(v, v_position.y), yi); - //std::cout << " add_edge " << xv1 << "("<< p1.x<< ") - " << xv2 <<"("<< p2.x << ")\n"; - g[e1].next = e2; - g[e2].next = e1; - g[e1].prev = e2; - g[e2].prev = e1; - //int n_yfiber=0; - BOOST_FOREACH( Fiber& yf, yfibers ) { // loop through all y-fibers for all x-intervals - if ( (xmin < yf.p1.x) && ( yf.p1.x < xmax ) ) {// potential intersection between y-fiber and x-interval - BOOST_FOREACH( Interval& yi, yf.ints ) { - //std::cout << "y-fiber " << n_yfiber++ << "\n"; - double ymin = yf.point(yi.lower).y ; - double ymax = yf.point(yi.upper).y ; - if ( (ymin < xf.p1.y) && (xf.p1.y < ymax) ) { - // there is an actual intersection btw x-interval and y-interval - // X interval xi on fiber xf intersects with Y interval yi on fiber yf - // intersection is at ( yf.p1.x, xf.p1.y , xf.p1.z ) - if (!yi.in_weave) { // add y-interval endpoints to weave - Point yp1( yf.point(yi.lower) ); - add_cl_vertex( yp1, yi, yp1.y ); - Point yp2( yf.point(yi.upper) ); - add_cl_vertex( yp2, yi, yp2.y ); - yi.in_weave = true; - } - // 3) intersection point, of type INT - - Vertex v = g.null_vertex(); - - Point v_position( yf.p1.x, xf.p1.y , xf.p1.z ); - // find neighbor to v - Vertex x_u, x_l; - - //std::cout << " fins neighbor to x= " << v_position.x << "\n"; - boost::tie( x_u, x_l ) = find_neighbor_vertices( VertexPair(v, v_position.x), xi ); - //std::cout << "found: x_u , x_l : " << x_u << " , " << x_l << "\n"; - Vertex y_u, y_l; - boost::tie( y_u, y_l ) = find_neighbor_vertices( VertexPair(v, v_position.y), yi ); - - //std::cout << "found: y_u , y_l : " << y_u << " , " << y_l << "\n"; - - add_int_vertex(v_position,x_l,x_u,y_l,y_u,xi,yi); - } // end intersection case - } // end y interval loop - } // end if(potential intersection) - } // end y fiber loop - - // now we've added an x-interval, we've gone through all the y-intervals - // if there isn't a single intersecting interval, then remove the x-interval as it is useless - assert( xi.intersections2.size() >= 2 ); - if ( xi.intersections2.size() == 2 ) { - clVertexSet.erase(xv1); - clVertexSet.erase(xv2); - g.clear_vertex(xv1); - g.clear_vertex(xv2); - g.remove_vertex(xv1); - g.remove_vertex(xv2); - } - - } // end zero-length interval check + // std::cout << "found: y_u , y_l : " << y_u << " , " << y_l << "\n"; + + add_int_vertex(v_position, x_l, x_u, y_l, y_u, xi, yi); + } // end intersection case + } // end y interval loop + } // end if(potential intersection) + } // end y fiber loop + + // now we've added an x-interval, we've gone through all the y-intervals + // if there isn't a single intersecting interval, then remove the x-interval as it is useless + assert(xi.intersections2.size() >= 2); + if (xi.intersections2.size() == 2) { + clVertexSet.erase(xv1); + clVertexSet.erase(xv2); + g.clear_vertex(xv1); + g.clear_vertex(xv2); + g.remove_vertex(xv1); + g.remove_vertex(xv2); + } + + } // end zero-length interval check } // x interval loop - } // end X-fiber loop + } // end X-fiber loop } // add a new CL-vertex to Weave, also adding it to the interval intersection-set, and to clVertices -Vertex SimpleWeave::add_cl_vertex( const Point& position, Interval& ival, double ipos) { - Vertex v = g.add_vertex(); +Vertex SimpleWeave::add_cl_vertex(const Point &position, Interval &ival, double ipos) { + Vertex v = g.add_vertex(); g[v].position = position; g[v].type = CL; - ival.intersections2.insert( VertexPair( v, ipos) ); // ?? this makes Interval depend on the WeaveGraph type + ival.intersections2.insert(VertexPair(v, ipos)); // ?? this makes Interval depend on the WeaveGraph type clVertexSet.insert(v); return v; } // add an internal vertex to the weave -void SimpleWeave::add_int_vertex( const Point& v_position, // position of new vertex - Vertex& x_l, // the x-lower vertex - Vertex& x_u, // the x-upper vertex - Vertex& y_l, // y-lower - Vertex& y_u, // y-upper - Interval& x_int, // the x-interval - Interval& y_int ) // the y-interval +void SimpleWeave::add_int_vertex(const Point &v_position, // position of new vertex + Vertex &x_l, // the x-lower vertex + Vertex &x_u, // the x-upper vertex + Vertex &y_l, // y-lower + Vertex &y_u, // y-upper + Interval &x_int, // the x-interval + Interval &y_int) // the y-interval { - //std::cout << " add_int_vertex " << "\n"; - Vertex v = g.add_vertex(); //hedi::add_vertex( VertexProps( v_position, INT ), g); + // std::cout << " add_int_vertex " << "\n"; + Vertex v = g.add_vertex(); // hedi::add_vertex( VertexProps( v_position, INT ), g); g[v].position = v_position; g[v].type = INT; - assert( g.has_edge(x_l,x_u) ); - assert( g.has_edge(x_u,x_l) ); - Edge xe_lu = g.edge(x_l,x_u); - Edge xe_ul = g.edge(x_u,x_l); + assert(g.has_edge(x_l, x_u)); + assert(g.has_edge(x_u, x_l)); + Edge xe_lu = g.edge(x_l, x_u); + Edge xe_ul = g.edge(x_u, x_l); Edge xe_lu_next = g[xe_lu].next; - Edge xe_lu_prev = g[xe_lu].prev; + Edge xe_lu_prev = g[xe_lu].prev; Edge xe_ul_next = g[xe_ul].next; - Edge xe_ul_prev = g[xe_ul].prev; - + Edge xe_ul_prev = g[xe_ul].prev; + // the next/prev data we need - Edge ye_lu_next, ye_lu_prev ; - Edge ye_ul_next, ye_ul_prev ; + Edge ye_lu_next, ye_lu_prev; + Edge ye_ul_next, ye_ul_prev; Edge ye_lu, ye_ul; - bool y_lu_edge = g.has_edge(y_l,y_u); // flag indicating existing y_l - y_u edge + bool y_lu_edge = g.has_edge(y_l, y_u); // flag indicating existing y_l - y_u edge // the case where y_l and y_u are already connected. - if ( y_lu_edge ) { - assert( g.has_edge( y_u, y_l ) ); // twin must also exist - ye_lu = g.edge( y_l, y_u); - ye_ul = g.edge( y_u, y_l); + if (y_lu_edge) { + assert(g.has_edge(y_u, y_l)); // twin must also exist + ye_lu = g.edge(y_l, y_u); + ye_ul = g.edge(y_u, y_l); ye_lu_next = g[ye_lu].next; - ye_lu_prev = g[ye_lu].prev; + ye_lu_prev = g[ye_lu].prev; ye_ul_next = g[ye_ul].next; - ye_ul_prev = g[ye_ul].prev; - } + ye_ul_prev = g[ye_ul].prev; + } // and now eight new edges to add - Edge xl_v = g.add_edge(x_l, v ); - Edge v_yl = g.add_edge(v , y_l); - Edge yl_v = g.add_edge(y_l, v ); - Edge v_xu = g.add_edge(v , x_u); - Edge xu_v = g.add_edge(x_u, v ); - Edge v_yu = g.add_edge(v , y_u); - Edge yu_v = g.add_edge(y_u, v ); - Edge v_xl = g.add_edge(v , x_l); + Edge xl_v = g.add_edge(x_l, v); + Edge v_yl = g.add_edge(v, y_l); + Edge yl_v = g.add_edge(y_l, v); + Edge v_xu = g.add_edge(v, x_u); + Edge xu_v = g.add_edge(x_u, v); + Edge v_yu = g.add_edge(v, y_u); + Edge yu_v = g.add_edge(y_u, v); + Edge v_xl = g.add_edge(v, x_l); // checks for special cases: if (xe_lu_prev == xe_ul) // xl hairpin xe_lu_prev = v_xl; @@ -211,7 +210,7 @@ void SimpleWeave::add_int_vertex( const Point& v_position, // position of new v xe_ul_prev = v_xu; if (xe_ul_next == xe_lu) xe_ul_next = xl_v; - if ( y_lu_edge ) { + if (y_lu_edge) { // the same checks for the y-edge if (ye_lu_prev == ye_ul) ye_lu_prev = v_yl; @@ -228,35 +227,46 @@ void SimpleWeave::add_int_vertex( const Point& v_position, // position of new v ye_ul_prev = v_yu; } // now set next/prev edges (there are 2*12=24 of these to do) - g[xe_lu_prev].next = xl_v; g[xl_v].prev = xe_lu_prev; - g[xl_v].next = v_yl; g[v_yl].prev = xl_v; - g[v_yl].next = ye_ul_next; g[ye_ul_next].prev = v_yl; - g[ye_lu_prev].next = yl_v; g[yl_v].prev = ye_lu_prev; - g[yl_v].next = v_xu; g[v_xu].prev = yl_v; - g[v_xu].next = xe_lu_next; g[xe_lu_next].prev = v_xu; - g[xe_ul_prev].next = xu_v; g[xu_v].prev = xe_ul_prev; - g[xu_v].next = v_yu; g[v_yu].prev = xu_v; - g[v_yu].next = ye_lu_next; g[ye_lu_next].prev = v_yu; - g[ye_ul_prev].next = yu_v; g[yu_v].prev = ye_ul_prev; - g[yu_v].next = v_xl; g[v_xl].prev = yu_v; - g[v_xl].next = xe_ul_next; g[xe_ul_next].prev = v_xl; + g[xe_lu_prev].next = xl_v; + g[xl_v].prev = xe_lu_prev; + g[xl_v].next = v_yl; + g[v_yl].prev = xl_v; + g[v_yl].next = ye_ul_next; + g[ye_ul_next].prev = v_yl; + g[ye_lu_prev].next = yl_v; + g[yl_v].prev = ye_lu_prev; + g[yl_v].next = v_xu; + g[v_xu].prev = yl_v; + g[v_xu].next = xe_lu_next; + g[xe_lu_next].prev = v_xu; + g[xe_ul_prev].next = xu_v; + g[xu_v].prev = xe_ul_prev; + g[xu_v].next = v_yu; + g[v_yu].prev = xu_v; + g[v_yu].next = ye_lu_next; + g[ye_lu_next].prev = v_yu; + g[ye_ul_prev].next = yu_v; + g[yu_v].prev = ye_ul_prev; + g[yu_v].next = v_xl; + g[v_xl].prev = yu_v; + g[v_xl].next = xe_ul_next; + g[xe_ul_next].prev = v_xl; // delete the old x-edges - g.remove_edge( x_l, x_u); - g.remove_edge( x_u, x_l); - if( y_lu_edge ) { // delete old y-edges - assert( g.has_edge( y_l, y_u) ); - assert( g.has_edge( y_u, y_l) ); - g.remove_edge( y_l, y_u); - g.remove_edge( y_u, y_l); + g.remove_edge(x_l, x_u); + g.remove_edge(x_u, x_l); + if (y_lu_edge) { // delete old y-edges + assert(g.has_edge(y_l, y_u)); + assert(g.has_edge(y_u, y_l)); + g.remove_edge(y_l, y_u); + g.remove_edge(y_u, y_l); } - + // finally add new intersection vertex to the interval sets - x_int.intersections2.insert( VertexPair( v, v_position.x ) ); - y_int.intersections2.insert( VertexPair( v, v_position.y ) ); + x_int.intersections2.insert(VertexPair(v, v_position.x)); + y_int.intersections2.insert(VertexPair(v, v_position.y)); } +} // namespace weave -} // end weave namespace - -} // end ocl namespace +} // namespace ocl // end file simple_weave.cpp diff --git a/src/algo/simple_weave.hpp b/src/algo/simple_weave.hpp index 491835d4..f3c2a563 100644 --- a/src/algo/simple_weave.hpp +++ b/src/algo/simple_weave.hpp @@ -1,23 +1,23 @@ /* $Id$ - * + * * Copyright (c) 2010-2011 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef SIMPLE_WEAVE_HPP #define SIMPLE_WEAVE_HPP @@ -30,35 +30,30 @@ namespace ocl { namespace weave { class SimpleWeave : public Weave { - public: - SimpleWeave() {} - virtual ~SimpleWeave() {} - void build(); - protected: - - /// add CL vertex to weave - /// sets position, type, and inserts the VertexPair into Interval::intersections - /// also adds the CL-vertex to clVertices, a list of cl-verts to be processed during face_traverse() - Vertex add_cl_vertex( const Point& position, Interval& interv, double ipos); - - /// add INT vertex to weave - /// the new vertex at v_position has neighbor vertices x_lower and x_upper in the x-direction on interval xi - /// and y_lower, y_upper in the y-direction of interval yi - /// Create new edges and delete old ones - void add_int_vertex( const Point& v_position, - Vertex& x_l, - Vertex& x_u, - Vertex& y_l, - Vertex& y_u, - Interval& xi, - Interval& yi ); - - /// given a vertex in the graph, find its upper and lower neighbor vertices - std::pair find_neighbor_vertices( VertexPair v_pair, Interval& ival); + public: + SimpleWeave() {} + virtual ~SimpleWeave() {} + void build(); + + protected: + /// add CL vertex to weave + /// sets position, type, and inserts the VertexPair into Interval::intersections + /// also adds the CL-vertex to clVertices, a list of cl-verts to be processed during face_traverse() + Vertex add_cl_vertex(const Point &position, Interval &interv, double ipos); + + /// add INT vertex to weave + /// the new vertex at v_position has neighbor vertices x_lower and x_upper in the x-direction on interval xi + /// and y_lower, y_upper in the y-direction of interval yi + /// Create new edges and delete old ones + void add_int_vertex(const Point &v_position, Vertex &x_l, Vertex &x_u, Vertex &y_l, Vertex &y_u, Interval &xi, + Interval &yi); + + /// given a vertex in the graph, find its upper and lower neighbor vertices + std::pair find_neighbor_vertices(VertexPair v_pair, Interval &ival); }; -} // end weave namespace +} // namespace weave -} // end ocl namespace +} // namespace ocl #endif // end file simple_weave.hpp diff --git a/src/algo/smart_weave.cpp b/src/algo/smart_weave.cpp index a57dca0a..bc642e62 100644 --- a/src/algo/smart_weave.cpp +++ b/src/algo/smart_weave.cpp @@ -1,23 +1,23 @@ /* $Id$ - * + * * Copyright (c) 2010-2011 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #include #include @@ -25,63 +25,61 @@ #include "smart_weave.hpp" -namespace ocl -{ +namespace ocl { -namespace weave -{ +namespace weave { // given a VertexPair and an Interval, in the Interval find the Vertex above and below the given vertex -std::pair SmartWeave::find_neighbor_vertices( VertexPair v_pair, Interval& ival, bool above_equality ) { - Interval::VertexPairIterator itr = ival.intersections2.lower_bound( v_pair ); // returns first that is not less than argument (equal or greater) - assert( itr != ival.intersections2.end() ); // we must find a lower_bound - Interval::VertexPairIterator v_above; - if ( above_equality ) +std::pair SmartWeave::find_neighbor_vertices(VertexPair v_pair, Interval &ival, bool above_equality) { + Interval::VertexPairIterator itr = + ival.intersections2.lower_bound(v_pair); // returns first that is not less than argument (equal or greater) + assert(itr != ival.intersections2.end()); // we must find a lower_bound + Interval::VertexPairIterator v_above; + if (above_equality) v_above = itr; // lower_bound returns one beyond the give key, i.e. what we want else { v_above = ++itr; --itr; } Interval::VertexPairIterator v_below = --itr; // this is the vertex below the given vertex - std::pair out; - out.first = v_above->first; // vertex above v (xu) + std::pair out; + out.first = v_above->first; // vertex above v (xu) out.second = v_below->first; // vertex below v (xl) return out; } - // this is the new smarter build() which uses less RAM void SmartWeave::build() { std::cout << " SimpleWeave::build()... \n"; - + // this adds all CL-vertices from x-intervals // it also populates the xi.intersections_fibers set of intersecting y-fibers // also add the first-crossing vertex and the last-crossing vertex - - //std::cout << " build2() add_vertices_x() ... " << std::flush ; + + // std::cout << " build2() add_vertices_x() ... " << std::flush ; add_vertices_x(); - //std::cout << " done.\n" << std::flush ; - // the same for y-intervals, add all CL-points, and intersections to the set. - //std::cout << " build2() add_vertices_y() ... " << std::flush ; + // std::cout << " done.\n" << std::flush ; + // the same for y-intervals, add all CL-points, and intersections to the set. + // std::cout << " build2() add_vertices_y() ... " << std::flush ; add_vertices_y(); - //std::cout << " done.\n" << std::flush ; - - //std::cout << " build2() looping over xfibers ... " << std::flush ; - BOOST_FOREACH( Fiber& xf, xfibers ) { + // std::cout << " done.\n" << std::flush ; + + // std::cout << " build2() looping over xfibers ... " << std::flush ; + BOOST_FOREACH (Fiber &xf, xfibers) { std::vector::iterator xi; - for( xi = xf.ints.begin(); xi < xf.ints.end(); xi++ ) { + for (xi = xf.ints.begin(); xi < xf.ints.end(); xi++) { std::set::iterator>::const_iterator current, prev; - if( xi->intersections_fibers.size() > 1 ) { + if (xi->intersections_fibers.size() > 1) { current = xi->intersections_fibers.begin(); prev = current++; - for( ; current != xi->intersections_fibers.end(); current++ ) { + for (; current != xi->intersections_fibers.end(); current++) { // for each x-interval, loop through the intersecting y-fibers - if( (*current - *prev) > 1 ) { - std::vector::iterator yi = find_interval_crossing_x( xf, *(*prev + 1) ); - add_vertex( xf, *(*prev + 1), xi , yi, FULLINT ); - if( (*current - *prev) > 2 ) { - yi = find_interval_crossing_x( xf, *(*current - 1) ); - add_vertex( xf, *(*current - 1), xi, yi, FULLINT ); + if ((*current - *prev) > 1) { + std::vector::iterator yi = find_interval_crossing_x(xf, *(*prev + 1)); + add_vertex(xf, *(*prev + 1), xi, yi, FULLINT); + if ((*current - *prev) > 2) { + yi = find_interval_crossing_x(xf, *(*current - 1)); + add_vertex(xf, *(*current - 1), xi, yi, FULLINT); } } prev = current; @@ -89,28 +87,29 @@ void SmartWeave::build() { } } } - //std::cout << " done.\n" << std::flush ; - - //std::cout << " build2() looping over yfibers ... " << std::flush ; - //std::cout << yfibers.size() << " fibers to loop over \n"<< std::flush ; - //int ny = 0; - BOOST_FOREACH( Fiber& yf, yfibers ) { - //std::cout << " fiber nr: " << ny++ << " has " << yf.ints.size() << " intervals\n" << std::flush ; + // std::cout << " done.\n" << std::flush ; + + // std::cout << " build2() looping over yfibers ... " << std::flush ; + // std::cout << yfibers.size() << " fibers to loop over \n"<< std::flush ; + // int ny = 0; + BOOST_FOREACH (Fiber &yf, yfibers) { + // std::cout << " fiber nr: " << ny++ << " has " << yf.ints.size() << " intervals\n" << std::flush ; std::vector::iterator yi; - //int ny_int=0; - for( yi = yf.ints.begin(); yi < yf.ints.end(); yi++ ) { - //std::cout << " interval nr: " << ny_int++ << " has yi->intersections_fibers.size()= " << yi->intersections_fibers.size() << "\n" << std::flush; + // int ny_int=0; + for (yi = yf.ints.begin(); yi < yf.ints.end(); yi++) { + // std::cout << " interval nr: " << ny_int++ << " has yi->intersections_fibers.size()= " << + // yi->intersections_fibers.size() << "\n" << std::flush; std::set::iterator>::iterator current, prev; - if( yi->intersections_fibers.size() > 1 ) { + if (yi->intersections_fibers.size() > 1) { current = yi->intersections_fibers.begin(); prev = current++; - for( ; current != yi->intersections_fibers.end(); current++ ) { - if( (*current - *prev) > 1 ) { - std::vector::iterator xi = find_interval_crossing_y( *(*prev + 1), yf ); - add_vertex( *(*prev + 1), yf, xi , yi, FULLINT ); - if( (*current - *prev) > 2 ) { - xi = find_interval_crossing_y( *(*current - 1), yf ); - add_vertex( *(*current - 1), yf, xi, yi, FULLINT ); + for (; current != yi->intersections_fibers.end(); current++) { + if ((*current - *prev) > 1) { + std::vector::iterator xi = find_interval_crossing_y(*(*prev + 1), yf); + add_vertex(*(*prev + 1), yf, xi, yi, FULLINT); + if ((*current - *prev) > 2) { + xi = find_interval_crossing_y(*(*current - 1), yf); + add_vertex(*(*current - 1), yf, xi, yi, FULLINT); } } prev = current; @@ -118,251 +117,249 @@ void SmartWeave::build() { } } } - //std::cout << " done.\n" << std::flush ; - + // std::cout << " done.\n" << std::flush ; + // std::cout << " SmartWeave::build() add_all_edges()... " << std::flush ; add_all_edges(); // std::cout << " done.\n" << std::flush ; } // add a new CL-vertex to Weave, also adding it to the interval intersection-set, and to clVertices -Vertex SmartWeave::add_cl_vertex( const Point& position, Interval& ival, double ipos) { - Vertex v = g.add_vertex(); +Vertex SmartWeave::add_cl_vertex(const Point &position, Interval &ival, double ipos) { + Vertex v = g.add_vertex(); g[v].position = position; g[v].type = CL; - ival.intersections2.insert( VertexPair( v, ipos) ); // ?? this makes Interval depend on the WeaveGraph type + ival.intersections2.insert(VertexPair(v, ipos)); // ?? this makes Interval depend on the WeaveGraph type clVertexSet.insert(v); return v; } void SmartWeave::add_vertices_x() { std::vector::iterator xf; - for( xf = xfibers.begin(); xf < xfibers.end(); xf++ ) { + for (xf = xfibers.begin(); xf < xfibers.end(); xf++) { std::vector::iterator xi; - for( xi = xf->ints.begin(); xi < xf->ints.end(); xi++ ) { + for (xi = xf->ints.begin(); xi < xf->ints.end(); xi++) { // find first and last fiber crossing this interval std::vector::iterator yf = yfibers.begin(); std::vector::iterator yi; - bool is_crossing = crossing_x( *yf, yi, *xi, *xf ); - while( (yfpoint( xi->lower ) ); - add_cl_vertex( lower, *xi, lower.x ); - Point upper( xf->point( xi->upper ) ); - add_cl_vertex( upper, *xi, upper.x ); + if (yf < yfibers.end()) { + Point lower(xf->point(xi->lower)); + add_cl_vertex(lower, *xi, lower.x); + Point upper(xf->point(xi->upper)); + add_cl_vertex(upper, *xi, upper.x); - add_vertex( *xf, *yf, xi, yi, INT ); // the first crossing vertex - xi->intersections_fibers.insert( yf ); - yi->intersections_fibers.insert( xf ); + add_vertex(*xf, *yf, xi, yi, INT); // the first crossing vertex + xi->intersections_fibers.insert(yf); + yi->intersections_fibers.insert(xf); - is_crossing = crossing_x( *yf, yi, *xi, *xf ); - while( (yfintersections_fibers.insert( yf ); - yi->intersections_fibers.insert( xf ); + add_vertex(*xf, *(--yf), xi, yi, INT); // the last crossing vertex + xi->intersections_fibers.insert(yf); + yi->intersections_fibers.insert(xf); } - }// end foreach x-interval - }// end foreach x-fiber + } // end foreach x-interval + } // end foreach x-fiber } void SmartWeave::add_vertices_y() { std::vector::iterator yf; - for( yf = yfibers.begin(); yf < yfibers.end(); yf++ ) { + for (yf = yfibers.begin(); yf < yfibers.end(); yf++) { std::vector::iterator yi; - for( yi = yf->ints.begin(); yi < yf->ints.end(); yi++ ) { + for (yi = yf->ints.begin(); yi < yf->ints.end(); yi++) { std::vector::iterator xf = xfibers.begin(); std::vector::iterator xi; - + // find first and last fiber crossing this interval - bool is_crossing = crossing_y( *xf, xi, *yi, *yf ); - while ( (xfpoint( yi->lower ) ); - add_cl_vertex( lower, *yi, lower.y ); - Point upper( yf->point( yi->upper ) ); - add_cl_vertex( upper, *yi, upper.y ); + if (xf < xfibers.end()) { + Point lower(yf->point(yi->lower)); + add_cl_vertex(lower, *yi, lower.y); + Point upper(yf->point(yi->upper)); + add_cl_vertex(upper, *yi, upper.y); - if( add_vertex( *xf, *yf, xi, yi, INT ) ) { // add_vertex returns false if vertex already exists - xi->intersections_fibers.insert( yf ); - yi->intersections_fibers.insert( xf ); + if (add_vertex(*xf, *yf, xi, yi, INT)) { // add_vertex returns false if vertex already exists + xi->intersections_fibers.insert(yf); + yi->intersections_fibers.insert(xf); } - bool is_crossing = crossing_y( *xf, xi, *yi, *yf ); - while ( (xfintersections_fibers.insert( yf ); - yi->intersections_fibers.insert( xf ); + if (add_vertex(*(--xf), *yf, xi, yi, INT)) { + xi->intersections_fibers.insert(yf); + yi->intersections_fibers.insert(xf); } } - }// end foreach x-interval - }// end foreach x-fiber + } // end foreach x-interval + } // end foreach x-fiber } -//crossing_x fiber -bool SmartWeave::crossing_x( Fiber& yf, std::vector::iterator& yi, Interval& xi, Fiber& xf ) { - //if the FIBER crosses the xi interval - if( (yf.p1.x >= xf.point( xi.lower ).x) && (yf.p1.x <= xf.point( xi.upper ).x) ) { - //for all the intervals of this y-fiber... +// crossing_x fiber +bool SmartWeave::crossing_x(Fiber &yf, std::vector::iterator &yi, Interval &xi, Fiber &xf) { + // if the FIBER crosses the xi interval + if ((yf.p1.x >= xf.point(xi.lower).x) && (yf.p1.x <= xf.point(xi.upper).x)) { + // for all the intervals of this y-fiber... std::vector::iterator it; - for( it = yf.ints.begin(); it < yf.ints.end(); it++ ) { - //find the first INTERVAL which crosses our xi interval - if( (yf.point( it->lower ).y <= xf.p1.y) && (yf.point( it->upper ).y >= xf.p1.y) ) { - //save the y-interval iterator - //and return true because we found an interval + for (it = yf.ints.begin(); it < yf.ints.end(); it++) { + // find the first INTERVAL which crosses our xi interval + if ((yf.point(it->lower).y <= xf.p1.y) && (yf.point(it->upper).y >= xf.p1.y)) { + // save the y-interval iterator + // and return true because we found an interval yi = it; return true; } } - //return false, there is no y-interval on this y-fiber crossing our xi interval + // return false, there is no y-interval on this y-fiber crossing our xi interval return false; } - //this y-fiber doesn't cross our xi interval - else + // this y-fiber doesn't cross our xi interval + else return false; } -//crossing_y fiber -bool SmartWeave::crossing_y( Fiber& xf, std::vector::iterator& xi, Interval& yi, Fiber& yf ) { - if( (xf.p1.y >= yf.point( yi.lower ).y) && (xf.p1.y <= yf.point( yi.upper ).y) ) { +// crossing_y fiber +bool SmartWeave::crossing_y(Fiber &xf, std::vector::iterator &xi, Interval &yi, Fiber &yf) { + if ((xf.p1.y >= yf.point(yi.lower).y) && (xf.p1.y <= yf.point(yi.upper).y)) { std::vector::iterator it; - for( it = xf.ints.begin(); it < xf.ints.end(); it++ ) { - if( (xf.point( it->lower ).x <= yf.p1.x) && (xf.point( it->upper ).x >= yf.p1.x) ) { + for (it = xf.ints.begin(); it < xf.ints.end(); it++) { + if ((xf.point(it->lower).x <= yf.p1.x) && (xf.point(it->upper).x >= yf.p1.x)) { xi = it; return true; } } return false; - } - else + } else return false; } -//find_interval_crossing_x -std::vector::iterator SmartWeave::find_interval_crossing_x( Fiber& xf, Fiber& yf ) { +// find_interval_crossing_x +std::vector::iterator SmartWeave::find_interval_crossing_x(Fiber &xf, Fiber &yf) { std::vector::iterator yi, xi; yi = yf.ints.begin(); - while( (yi::iterator SmartWeave::find_interval_crossing_y( Fiber& xf, Fiber& yf ) { +// crossing_y interval +std::vector::iterator SmartWeave::find_interval_crossing_y(Fiber &xf, Fiber &yf) { std::vector::iterator xi, yi; xi = xf.ints.begin(); - while( (xi::iterator xi, - std::vector::iterator yi, - enum VertexType type ) { - //test if vertex exists - BOOST_FOREACH( std::vector::iterator it_xf, yi->intersections_fibers ) { - if( *it_xf == xf ) +// add_vertex +bool SmartWeave::add_vertex(Fiber &xf, Fiber &yf, std::vector::iterator xi, + std::vector::iterator yi, enum VertexType type) { + // test if vertex exists + BOOST_FOREACH (std::vector::iterator it_xf, yi->intersections_fibers) { + if (*it_xf == xf) return false; } - Point v_position( yf.p1.x, xf.p1.y, xf.p1.z ); - Vertex v =g.add_vertex(); + Point v_position(yf.p1.x, xf.p1.y, xf.p1.z); + Vertex v = g.add_vertex(); g[v].position = v_position; g[v].type = type; - g[v].xi= xi; - g[v].yi= yi; - xi->intersections2.insert( VertexPair( v, v_position.x ) ); - yi->intersections2.insert( VertexPair( v, v_position.y ) ); + g[v].xi = xi; + g[v].yi = yi; + xi->intersections2.insert(VertexPair(v, v_position.x)); + yi->intersections2.insert(VertexPair(v, v_position.y)); return true; } -//add_all_edges -void SmartWeave::add_all_edges() -{ - std::vector vertices = g.vertices(); +// add_all_edges +void SmartWeave::add_all_edges() { + std::vector vertices = g.vertices(); std::cout << "There are " << vertices.size() << " vertices.\n"; - BOOST_FOREACH( Vertex& vertex, vertices ) { - if( (g[vertex].type == INT) || (g[vertex].type == FULLINT) ) { - std::vector adjacent_vertices; - std::vector::iterator adj_itr; - std::vector in_edges, out_edges; - std::vector::iterator in_edge_itr, out_edge_itr; + BOOST_FOREACH (Vertex &vertex, vertices) { + if ((g[vertex].type == INT) || (g[vertex].type == FULLINT)) { + std::vector adjacent_vertices; + std::vector::iterator adj_itr; + std::vector in_edges, out_edges; + std::vector::iterator in_edge_itr, out_edge_itr; Vertex x_u, x_l, y_u, y_l; - boost::tie( x_u, x_l ) = find_neighbor_vertices( VertexPair(vertex, g[vertex].position.x), *(g[vertex].xi), false ); - boost::tie( y_u, y_l ) = find_neighbor_vertices( VertexPair(vertex, g[vertex].position.y), *(g[vertex].yi), false ); - - adjacent_vertices.push_back( x_l ); - adjacent_vertices.push_back( y_u ); - adjacent_vertices.push_back( x_u ); - adjacent_vertices.push_back( y_l ); - - for( adj_itr=adjacent_vertices.begin(); adj_itr adjacent_vertices; Vertex x_u, x_l, y_u, y_l; - boost::tie( x_u, x_l ) = find_neighbor_vertices( VertexPair(vertex, g[vertex].position.x), *(g[vertex].xi), false ); - boost::tie( y_u, y_l ) = find_neighbor_vertices( VertexPair(vertex, g[vertex].position.y), *(g[vertex].yi), false ); + boost::tie( x_u, x_l ) = find_neighbor_vertices( VertexPair(vertex, g[vertex].position.x), *(g[vertex].xi), + false ); boost::tie( y_u, y_l ) = find_neighbor_vertices( VertexPair(vertex, g[vertex].position.y), + *(g[vertex].yi), false ); if( g[x_l].type == INT ) adjacent_vertices.push_back( x_l ); if( g[y_u].type == INT ) adjacent_vertices.push_back( y_u ); if( g[x_u].type == INT ) adjacent_vertices.push_back( x_u ); if( g[y_l].type == INT ) adjacent_vertices.push_back( y_l ); - + if( adjacent_vertices.size() == 1 ) { Edge in, out; std::vector::iterator adj_itr = adjacent_vertices.begin(); @@ -384,7 +381,7 @@ void SmartWeave::add_all_edges() std::vector::iterator edge_itr; for( adj_itr=adjacent_vertices.begin(); adj_itr. -*/ + */ #ifndef SMART_WEAVE_HPP #define SMART_WEAVE_HPP @@ -30,29 +30,27 @@ namespace ocl { namespace weave { class SmartWeave : public Weave { - public: - SmartWeave() {} - virtual ~SmartWeave() {} - void build(); - protected: - void add_vertices_x(); - void add_vertices_y(); - bool crossing_x( Fiber& yf, std::vector::iterator& yi, Interval& xi, Fiber& xf ); - bool crossing_y( Fiber& xf, std::vector::iterator& xi, Interval& yi, Fiber& yf ); - std::vector::iterator find_interval_crossing_x( Fiber& xf, Fiber& yf ); - std::vector::iterator find_interval_crossing_y( Fiber& xf, Fiber& yf ); - Vertex add_cl_vertex( const Point& position, Interval& ival, double ipos); - bool add_vertex( Fiber& xf, - Fiber& yf, - std::vector::iterator xi, - std::vector::iterator yi, - enum VertexType type ); - void add_all_edges(); - std::pair find_neighbor_vertices( VertexPair v_pair, Interval& ival, bool above_equality ); + public: + SmartWeave() {} + virtual ~SmartWeave() {} + void build(); + + protected: + void add_vertices_x(); + void add_vertices_y(); + bool crossing_x(Fiber &yf, std::vector::iterator &yi, Interval &xi, Fiber &xf); + bool crossing_y(Fiber &xf, std::vector::iterator &xi, Interval &yi, Fiber &yf); + std::vector::iterator find_interval_crossing_x(Fiber &xf, Fiber &yf); + std::vector::iterator find_interval_crossing_y(Fiber &xf, Fiber &yf); + Vertex add_cl_vertex(const Point &position, Interval &ival, double ipos); + bool add_vertex(Fiber &xf, Fiber &yf, std::vector::iterator xi, std::vector::iterator yi, + enum VertexType type); + void add_all_edges(); + std::pair find_neighbor_vertices(VertexPair v_pair, Interval &ival, bool above_equality); }; -} // end weave namespace +} // namespace weave -} // end ocl namespace +} // namespace ocl #endif // end file smart_weave.hpp diff --git a/src/algo/tsp.hpp b/src/algo/tsp.hpp index 5c1e2b3c..cdc66705 100644 --- a/src/algo/tsp.hpp +++ b/src/algo/tsp.hpp @@ -1,36 +1,36 @@ /* $Id$ - * + * * Copyright (c) 2010-2011 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef TSP_H #define TSP_H -#include -#include +#include #include +#include #include -#include +#include #include #include -#include #include +#include #include @@ -41,15 +41,12 @@ namespace tsp { // loosely based on metric tsp example: // http://www.boost.org/doc/libs/1_46_1/libs/graph/test/metric_tsp_approx.cpp -//add edges to the graph (for each node connect it to all other nodes) -template< typename VertexListGraph, - typename PointContainer, - typename WeightMap, - typename VertexIndexMap> -void connectAllEuclidean(VertexListGraph& g, - const PointContainer& points, // vector of (x,y) points - WeightMap wmap, // Property maps passed by value - const VertexIndexMap vmap) // Property maps passed by value +// add edges to the graph (for each node connect it to all other nodes) +template +void connectAllEuclidean(VertexListGraph &g, + const PointContainer &points, // vector of (x,y) points + WeightMap wmap, // Property maps passed by value + const VertexIndexMap vmap) // Property maps passed by value { using namespace boost; using namespace std; @@ -61,9 +58,8 @@ void connectAllEuclidean(VertexListGraph& g, for (VItr src(verts.first); src != verts.second; src++) { for (VItr dest(src); dest != verts.second; dest++) { if (dest != src) { - double weight( sqrt( - pow(static_cast( points[vmap[*src ]].x - points[vmap[*dest]].x), 2.0) + - pow(static_cast( points[vmap[*dest]].y - points[vmap[*src ]].y), 2.0)) ); + double weight(sqrt(pow(static_cast(points[vmap[*src]].x - points[vmap[*dest]].x), 2.0) + + pow(static_cast(points[vmap[*dest]].y - points[vmap[*src]].y), 2.0))); boost::tie(e, inserted) = add_edge(*src, *dest, g); wmap[e] = weight; // passed by value?? } @@ -72,43 +68,43 @@ void connectAllEuclidean(VertexListGraph& g, } class TSPSolver { - typedef boost::adjacency_matrix< boost::undirectedS, - boost::no_property, - boost::property< boost::edge_weight_t, double, - boost::property< boost::edge_index_t, long unsigned int> >, - boost::no_property - > Graph; + typedef boost::adjacency_matrix< + boost::undirectedS, boost::no_property, + boost::property>, + boost::no_property> + Graph; typedef boost::graph_traits::vertex_descriptor Vertex; typedef boost::graph_traits::edge_descriptor Edge; typedef boost::property_map::type WeightMap; - typedef std::vector< boost::simple_point > PointSet; // was std::set - typedef std::vector< Vertex > Container; - -public: - TSPSolver () {} + typedef std::vector> PointSet; // was std::set + typedef std::vector Container; + + public: + TSPSolver() {} virtual ~TSPSolver() { if (g) delete g; } void run() { - g = new Graph( points.size() ); + g = new Graph(points.size()); // connect all vertices - WeightMap weight_map = boost::get( boost::edge_weight, *g); - connectAllEuclidean( *g, points, weight_map, boost::get( boost::vertex_index, *g) ); + WeightMap weight_map = boost::get(boost::edge_weight, *g); + connectAllEuclidean(*g, points, weight_map, boost::get(boost::vertex_index, *g)); length = 0.0; // Run the TSP approx, creating the visitor on the fly. - boost::metric_tsp_approx(*g, boost::make_tsp_tour_len_visitor(*g, std::back_inserter(output), length, weight_map) ); - //length = len; - //std::cout << "Number of points: " << boost::num_vertices(*g) << std::endl; - //std::cout << "Number of edges: " << boost::num_edges(*g) << std::endl; - //std::cout << "Length of tour: " << len << std::endl; - //std::cout << "vertices in tour: " << output.size() << std::endl; - //std::cout << "Elapsed: " << t.elapsed() << std::endl; + boost::metric_tsp_approx(*g, + boost::make_tsp_tour_len_visitor(*g, std::back_inserter(output), length, weight_map)); + // length = len; + // std::cout << "Number of points: " << boost::num_vertices(*g) << std::endl; + // std::cout << "Number of edges: " << boost::num_edges(*g) << std::endl; + // std::cout << "Length of tour: " << len << std::endl; + // std::cout << "vertices in tour: " << output.size() << std::endl; + // std::cout << "Elapsed: " << t.elapsed() << std::endl; } void addPoint(double x, double y) { boost::simple_point pnt; - pnt.x=x; - pnt.y=y; + pnt.x = x; + pnt.y = y; points.push_back(pnt); } void reset() { @@ -118,31 +114,28 @@ class TSPSolver { delete g; } void printOutput() const { - int n=0; - BOOST_FOREACH( Vertex v, output ) { - std::cout << n++ << " : " << v << "\n" ; + int n = 0; + BOOST_FOREACH (Vertex v, output) { + std::cout << n++ << " : " << v << "\n"; } } - double getLength() const { - return length; - } + double getLength() const { return length; } boost::python::list getOutput() const { boost::python::list plist; - BOOST_FOREACH(Vertex v, output) { - plist.append( v ); + BOOST_FOREACH (Vertex v, output) { + plist.append(v); } return plist; } - -protected: + + protected: Container output; PointSet points; - Graph* g; + Graph *g; double length; }; +} // namespace tsp -} // end tsp namespace - -} // end ocl namespace +} // namespace ocl #endif diff --git a/src/algo/waterline.cpp b/src/algo/waterline.cpp index c6d0f36a..18f52bb8 100644 --- a/src/algo/waterline.cpp +++ b/src/algo/waterline.cpp @@ -1,57 +1,55 @@ /* $Id$ - * + * * Copyright (c) 2010-2011 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ -#include +#include #ifdef _OPENMP - #include +#include #endif +#include "batchpushcutter.hpp" #include "millingcutter.hpp" #include "point.hpp" #include "triangle.hpp" #include "waterline.hpp" -#include "batchpushcutter.hpp" // #include "weave.hpp" #include "simple_weave.hpp" #include "smart_weave.hpp" -namespace ocl -{ +namespace ocl { //******** ********************** */ Waterline::Waterline() { subOp.clear(); - subOp.push_back( new BatchPushCutter() ); - subOp.push_back( new BatchPushCutter() ); + subOp.push_back(new BatchPushCutter()); + subOp.push_back(new BatchPushCutter()); subOp[0]->setXDirection(); subOp[1]->setYDirection(); - nthreads=1; + nthreads = 1; #ifdef _OPENMP nthreads = omp_get_num_procs(); - //omp_set_dynamic(0); - //omp_set_nested(1); + // omp_set_dynamic(0); + // omp_set_nested(1); #endif - } Waterline::~Waterline() { @@ -61,17 +59,16 @@ Waterline::~Waterline() { subOp.clear(); } - // run the batchpuschutter sub-operations to get x- and y-fibers // pass the fibers to weave, and process the weave to get waterline-loops void Waterline::run2() { init_fibers(); subOp[0]->run(); // these two are independent, so could/should run in parallel subOp[1]->run(); - - xfibers = *( subOp[0]->getFibers() ); - yfibers = *( subOp[1]->getFibers() ); - + + xfibers = *(subOp[0]->getFibers()); + yfibers = *(subOp[1]->getFibers()); + weave_process2(); } @@ -79,14 +76,13 @@ void Waterline::run() { init_fibers(); subOp[0]->run(); // these two are independent, so could/should run in parallel subOp[1]->run(); - - xfibers = *( subOp[0]->getFibers() ); - yfibers = *( subOp[1]->getFibers() ); - + + xfibers = *(subOp[0]->getFibers()); + yfibers = *(subOp[1]->getFibers()); + weave_process(); } - void Waterline::reset() { xfibers.clear(); yfibers.clear(); @@ -97,85 +93,85 @@ void Waterline::reset() { void Waterline::weave_process() { // std::cout << "Weave...\n" << std::flush; weave::SimpleWeave weave; - BOOST_FOREACH( Fiber f, xfibers ) { + BOOST_FOREACH (Fiber f, xfibers) { weave.addFiber(f); } - BOOST_FOREACH( Fiber f, yfibers ) { + BOOST_FOREACH (Fiber f, yfibers) { weave.addFiber(f); } - - //std::cout << "Weave::build()..." << std::flush; - weave.build(); + + // std::cout << "Weave::build()..." << std::flush; + weave.build(); // std::cout << "done.\n"; - + // std::cout << "Weave::face traverse()..."; weave.face_traverse(); // std::cout << "done.\n"; // std::cout << "Weave::get_loops()..."; loops = weave.getLoops(); - // std::cout << "done.\n"; + // std::cout << "done.\n"; } void Waterline::weave_process2() { // std::cout << "Weave...\n" << std::flush; weave::SmartWeave weave; - BOOST_FOREACH( Fiber f, xfibers ) { + BOOST_FOREACH (Fiber f, xfibers) { weave.addFiber(f); } - BOOST_FOREACH( Fiber f, yfibers ) { + BOOST_FOREACH (Fiber f, yfibers) { weave.addFiber(f); } - - //std::cout << "Weave::build2()..." << std::flush; - weave.build(); + + // std::cout << "Weave::build2()..." << std::flush; + weave.build(); // std::cout << "done.\n"; - + // std::cout << "Weave::face traverse()..."; weave.face_traverse(); // std::cout << "done.\n"; // std::cout << "Weave::get_loops()..."; loops = weave.getLoops(); - // std::cout << "done.\n"; + // std::cout << "done.\n"; } void Waterline::init_fibers() { // std::cout << " Waterline::init_fibers()\n"; - double minx = surf->bb.minpt.x - 2*cutter->getRadius(); - double maxx = surf->bb.maxpt.x + 2*cutter->getRadius(); - double miny = surf->bb.minpt.y - 2*cutter->getRadius(); - double maxy = surf->bb.maxpt.y + 2*cutter->getRadius(); - int Nx = (int)( (maxx-minx)/sampling ); - int Ny = (int)( (maxy-miny)/sampling ); - std::vector xvals = generate_range(minx,maxx,Nx); - std::vector yvals = generate_range(miny,maxy,Ny); - BOOST_FOREACH( double y, yvals ) { - Point p1 = Point( minx, y, zh ); - Point p2 = Point( maxx, y, zh ); - Fiber f = Fiber( p1 , p2 ); - subOp[0]->appendFiber( f ); + double minx = surf->bb.minpt.x - 2 * cutter->getRadius(); + double maxx = surf->bb.maxpt.x + 2 * cutter->getRadius(); + double miny = surf->bb.minpt.y - 2 * cutter->getRadius(); + double maxy = surf->bb.maxpt.y + 2 * cutter->getRadius(); + int Nx = (int)((maxx - minx) / sampling); + int Ny = (int)((maxy - miny) / sampling); + std::vector xvals = generate_range(minx, maxx, Nx); + std::vector yvals = generate_range(miny, maxy, Ny); + BOOST_FOREACH (double y, yvals) { + Point p1 = Point(minx, y, zh); + Point p2 = Point(maxx, y, zh); + Fiber f = Fiber(p1, p2); + subOp[0]->appendFiber(f); } - BOOST_FOREACH( double x, xvals ) { - Point p1 = Point( x, miny, zh ); - Point p2 = Point( x, maxy, zh ); - Fiber f = Fiber( p1 , p2 ); - subOp[1]->appendFiber( f ); + BOOST_FOREACH (double x, xvals) { + Point p1 = Point(x, miny, zh); + Point p2 = Point(x, maxy, zh); + Fiber f = Fiber(p1, p2); + subOp[1]->appendFiber(f); } } // return a double-vector [ start , ... , end ] with N elements // for generating fibers. -std::vector Waterline::generate_range( double start, double end, int N) const { +std::vector Waterline::generate_range(double start, double end, int N) const { std::vector output; - double d = (end-start)/ (double)N; + double d = (end - start) / (double)N; double v = start; - for (int n=0; n< (N+1); ++n) { - output.push_back( v ); - v=v+d; + for (int n = 0; n < (N + 1); ++n) { + output.push_back(v); + v = v + d; } return output; } -}// end namespace +} // namespace ocl // end file waterline.cpp diff --git a/src/algo/waterline.hpp b/src/algo/waterline.hpp index 912260b7..bd80d4a1 100644 --- a/src/algo/waterline.hpp +++ b/src/algo/waterline.hpp @@ -1,23 +1,23 @@ /* $Id$ - * + * * Copyright (c) 2010-2011 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef WATERLINE_H #define WATERLINE_H @@ -26,15 +26,12 @@ #include #include -#include "point.hpp" -#include "fiber.hpp" #include "batchpushcutter.hpp" +#include "fiber.hpp" #include "operation.hpp" +#include "point.hpp" - -namespace ocl -{ - +namespace ocl { /// \brief a Waterline toolpath follows the shape of the model at a constant z-height in the xy-plane @@ -42,51 +39,44 @@ namespace ocl /// from an STL-model. Waterline uses two BatchPushCutter sub-operations to find out where the CL-points are located /// and a Weave to split and order the CL-points correctly into loops. class Waterline : public Operation { - public: - /// create an empty Waterline object - Waterline(); - virtual ~Waterline(); - - /// Set the z-coordinate for the waterline we generate - void setZ(const double z) { - zh = z; - } - /// run the Waterline algorithm. setSTL, setCutter, setSampling, and setZ must - /// be called before a call to run() - virtual void run(); - virtual void run2(); - - /// returns a vector< vector< Point > > with the resulting waterline loops - std::vector< std::vector > getLoops() const { - return loops; - } - void reset(); - - protected: - /// from xfibers and yfibers, build the weave, run face-traverse, and write toolpaths to loops - void weave_process(); - void weave_process2(); - - /// initialization of fibers - void init_fibers(); - /// x and y-coordinates for fiber generation - std::vector generate_range( double start, double end, int N) const; - - // DATA - /// the z-height for this Waterline - double zh; - /// the results of this operation, a list of loops - std::vector< std::vector > loops; - - /// x-fibers for this operation - std::vector xfibers; - /// y-fibers for this operation - std::vector yfibers; - -}; + public: + /// create an empty Waterline object + Waterline(); + virtual ~Waterline(); + + /// Set the z-coordinate for the waterline we generate + void setZ(const double z) { zh = z; } + /// run the Waterline algorithm. setSTL, setCutter, setSampling, and setZ must + /// be called before a call to run() + virtual void run(); + virtual void run2(); + + /// returns a vector< vector< Point > > with the resulting waterline loops + std::vector> getLoops() const { return loops; } + void reset(); + + protected: + /// from xfibers and yfibers, build the weave, run face-traverse, and write toolpaths to loops + void weave_process(); + void weave_process2(); + /// initialization of fibers + void init_fibers(); + /// x and y-coordinates for fiber generation + std::vector generate_range(double start, double end, int N) const; + // DATA + /// the z-height for this Waterline + double zh; + /// the results of this operation, a list of loops + std::vector> loops; + + /// x-fibers for this operation + std::vector xfibers; + /// y-fibers for this operation + std::vector yfibers; +}; -} // end namespace +} // namespace ocl #endif diff --git a/src/algo/weave.cpp b/src/algo/weave.cpp index ab41c8a5..650a0d45 100644 --- a/src/algo/weave.cpp +++ b/src/algo/weave.cpp @@ -1,23 +1,23 @@ /* $Id$ - * + * * Copyright (c) 2010-2011 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #include #include @@ -25,19 +25,16 @@ #include "weave.hpp" +namespace ocl { -namespace ocl -{ - -namespace weave -{ +namespace weave { int VertexProps::count = 0; -void Weave::addFiber(Fiber& f) { - if ( f.dir.xParallel() && !f.empty() ) { +void Weave::addFiber(Fiber &f) { + if (f.dir.xParallel() && !f.empty()) { xfibers.push_back(f); - } else if ( f.dir.yParallel() && !f.empty() ) { + } else if (f.dir.yParallel() && !f.empty()) { yfibers.push_back(f); } else if (!f.empty()) { assert(0); // fiber must be either x or y @@ -46,78 +43,75 @@ void Weave::addFiber(Fiber& f) { // traverse the graph putting loops of vertices into the loops variable // this figure illustrates next-pointers: http://www.anderswallin.net/wp-content/uploads/2011/05/weave2_zoom.png -void Weave::face_traverse() { +void Weave::face_traverse() { // std::cout << " traversing graph with " << clVertexSet.size() << " cl-points\n"; - while ( !clVertexSet.empty() ) { // while unprocessed cl-vertices remain - std::vector loop; // start on a new loop + while (!clVertexSet.empty()) { // while unprocessed cl-vertices remain + std::vector loop; // start on a new loop Vertex current = *(clVertexSet.begin()); Vertex first = current; - - do { // traverse around the loop - assert( g[current].type == CL ); // we only want cl-points in the loop + + do { // traverse around the loop + assert(g[current].type == CL); // we only want cl-points in the loop loop.push_back(current); - clVertexSet.erase(current); // remove from set of unprocesser cl-verts - std::vector outEdges = g.out_edges(current); // find the edge to follow - //if (outEdges.size() != 1 ) - // std::cout << " outEdges.size() = " << outEdges.size() << "\n"; - assert( outEdges.size() == 1 ); // cl-points are always at ends of intervals, so they have only one out-edge - Edge currentEdge = outEdges[0]; - do { // following next, find a CL point - current = g.target(currentEdge); + clVertexSet.erase(current); // remove from set of unprocesser cl-verts + std::vector outEdges = g.out_edges(current); // find the edge to follow + // if (outEdges.size() != 1 ) + // std::cout << " outEdges.size() = " << outEdges.size() << "\n"; + assert(outEdges.size() == 1); // cl-points are always at ends of intervals, so they have only one out-edge + Edge currentEdge = outEdges[0]; + do { // following next, find a CL point + current = g.target(currentEdge); currentEdge = g[currentEdge].next; - } while ( g[current].type != CL ); - } while (current!=first); // end the loop when we arrive at the start - + } while (g[current].type != CL); + } while (current != first); // end the loop when we arrive at the start + loops.push_back(loop); // add the processed loop to the master list of all loops } } - -std::vector< std::vector > Weave::getLoops() const { - std::vector< std::vector > loop_list; - BOOST_FOREACH( std::vector loop, loops ) { +std::vector> Weave::getLoops() const { + std::vector> loop_list; + BOOST_FOREACH (std::vector loop, loops) { std::vector point_list; - BOOST_FOREACH( Vertex v, loop ) { - point_list.push_back( g[v].position ); + BOOST_FOREACH (Vertex v, loop) { + point_list.push_back(g[v].position); } loop_list.push_back(point_list); } return loop_list; } - // this can cause a build error when both face and vertex descriptors have the same type // i.e. unsigned int (?) // operator[] below "g[*itr].type" then looks for FaceProps.type which does not exist... -void Weave::printGraph() { - std::cout << " number of vertices: " << g.num_vertices() << "\n"; - std::cout << " number of edges: " << g.num_edges() << "\n"; +void Weave::printGraph() { + std::cout << " number of vertices: " << g.num_vertices() << "\n"; + std::cout << " number of edges: " << g.num_edges() << "\n"; - int n=0, n_cl=0, n_internal=0; - BOOST_FOREACH(Vertex v, g.vertices() ) { - if ( g[v].type == CL ) + int n = 0, n_cl = 0, n_internal = 0; + BOOST_FOREACH (Vertex v, g.vertices()) { + if (g[v].type == CL) ++n_cl; else ++n_internal; ++n; } - + std::cout << " counted " << n << " vertices\n"; std::cout << " CL-nodes: " << n_cl << "\n"; std::cout << " internal-nodes: " << n_internal << "\n"; } - + // string representation -std::string Weave::str() { +std::string Weave::str() { std::ostringstream o; o << "Weave2\n"; o << " " << xfibers.size() << " X-fibers\n"; o << " " << yfibers.size() << " Y-fibers\n"; return o.str(); } - -} // end weave namespace +} // namespace weave -} // end ocl namespace +} // namespace ocl // end file weave.cpp diff --git a/src/algo/weave.hpp b/src/algo/weave.hpp index acf4c740..2e2583b2 100644 --- a/src/algo/weave.hpp +++ b/src/algo/weave.hpp @@ -1,32 +1,31 @@ /* $Id$ - * + * * Copyright (c) 2010-2011 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef WEAVE_HPP #define WEAVE_HPP #include - #include "fiber.hpp" -#include "weave_typedef.hpp" #include "halfedgediagram.hpp" +#include "weave_typedef.hpp" namespace ocl { @@ -34,33 +33,33 @@ namespace weave { // Abstract base-class for weave-implementations. build() must be implemented in sub-class! class Weave { - public: - Weave() {} - virtual ~Weave() {} - /// add Fiber f to the graph - /// each fiber should be either in the X or Y-direction - /// FIXME: separate addXFiber and addYFiber methods? - void addFiber(Fiber& f); - /// from the list of fibers, build a graph - virtual void build() = 0; - /// run planar_face_traversal to get the waterline loops - void face_traverse(); - /// return list of loops - std::vector< std::vector > getLoops() const; - /// string representation - std::string str() ; - void printGraph() ; - - protected: - WeaveGraph g; ///< the weave-graph - std::vector< std::vector > loops; ///< output: list of loops in this weave - std::vector xfibers; ///< the X-fibers - std::vector yfibers; ///< the Y-fibers - std::set clVertexSet; ///< set of CL-points + public: + Weave() {} + virtual ~Weave() {} + /// add Fiber f to the graph + /// each fiber should be either in the X or Y-direction + /// FIXME: separate addXFiber and addYFiber methods? + void addFiber(Fiber &f); + /// from the list of fibers, build a graph + virtual void build() = 0; + /// run planar_face_traversal to get the waterline loops + void face_traverse(); + /// return list of loops + std::vector> getLoops() const; + /// string representation + std::string str(); + void printGraph(); + + protected: + WeaveGraph g; ///< the weave-graph + std::vector> loops; ///< output: list of loops in this weave + std::vector xfibers; ///< the X-fibers + std::vector yfibers; ///< the Y-fibers + std::set clVertexSet; ///< set of CL-points }; -} // end weave namespace +} // namespace weave -} // end ocl namespace +} // namespace ocl #endif // end file weave.hpp diff --git a/src/algo/weave_typedef.hpp b/src/algo/weave_typedef.hpp index 93ae3c70..b59cb899 100644 --- a/src/algo/weave_typedef.hpp +++ b/src/algo/weave_typedef.hpp @@ -1,23 +1,23 @@ /* $Id$ - * + * * Copyright (c) 2010-2011 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef WEAVE_TYPEDEF_H #define WEAVE_TYPEDEF_H @@ -28,53 +28,47 @@ namespace ocl { namespace weave { - // we use the traits-class here so that EdgeProps can have Edge as a member -typedef boost::adjacency_list_traits::edge_descriptor Edge; +typedef boost::adjacency_list_traits::edge_descriptor + Edge; /// vertex type: CL-point, internal point, adjacent point -enum VertexType {CL, CL_DONE, ADJ, TWOADJ, INT, FULLINT}; +enum VertexType { CL, CL_DONE, ADJ, TWOADJ, INT, FULLINT }; /// vertex properties struct VertexProps { - VertexProps() { - init(); - } + VertexProps() { init(); } /// construct vertex at position p with type t - VertexProps( Point p, VertexType t) { - position=p; - type=t; + VertexProps(Point p, VertexType t) { + position = p; + type = t; init(); } /// construct vertex at position p with type t - VertexProps( Point p, VertexType t, std::vector::iterator x, std::vector::iterator y ) - : xi( x ), yi( y ) { - position=p; - type=t; + VertexProps(Point p, VertexType t, std::vector::iterator x, std::vector::iterator y) + : xi(x), yi(y) { + position = p; + type = t; init(); } - + void init() { index = count; count++; } VertexType type; -// HE data + // HE data /// the position of the vertex Point position; /// index of vertex int index; /// global vertex count static int count; - + // x interval std::vector::iterator xi; // y interval std::vector::iterator yi; - }; /// edge properties @@ -82,68 +76,64 @@ struct EdgeProps { EdgeProps() {} /// the next edge, counterclockwise, from this edge Edge next; - /// previous edge, to make Weave::build() faster, since we avoid calling hedi::previous_edge() + /// previous edge, to make Weave::build() faster, since we avoid calling hedi::previous_edge() Edge prev; /// the twin edge Edge twin; }; -typedef unsigned int Face; +typedef unsigned int Face; /// properties of a face in the weave struct FaceProps { /// create face with given edge, generator, and type - FaceProps( Edge e ) { - edge = e; - } + FaceProps(Edge e) { edge = e; } /// face index Face idx; /// one edge that bounds this face Edge edge; }; - - // the graph type for the weave -typedef ocl::hedi::HEDIGraph< boost::listS, // out-edges stored here - boost::listS, // vertex set stored here - boost::bidirectionalS, // undirecgted or bidirectional graph? - VertexProps, // vertex properties - EdgeProps, // edge properties - FaceProps, // face properties - boost::no_property, // graph properties - boost::listS // edge storage - > WeaveGraph; +typedef ocl::hedi::HEDIGraph + WeaveGraph; typedef WeaveGraph::Vertex Vertex; -typedef WeaveGraph::VertexItr VertexItr; +typedef WeaveGraph::VertexItr VertexItr; -//typedef boost::graph_traits< WeaveGraph >::vertex_descriptor Vertex; +// typedef boost::graph_traits< WeaveGraph >::vertex_descriptor Vertex; // -// typedef boost::graph_traits< WeaveGraph >::edge_descriptor Edge; -//typedef boost::graph_traits< WeaveGraph >::edge_iterator EdgeItr; -//typedef boost::graph_traits< WeaveGraph >::out_edge_iterator OutEdgeItr; -//typedef boost::graph_traits< WeaveGraph >::adjacency_iterator AdjacencyItr; +// typedef boost::graph_traits< WeaveGraph >::edge_descriptor Edge; +// typedef boost::graph_traits< WeaveGraph >::edge_iterator EdgeItr; +// typedef boost::graph_traits< WeaveGraph >::out_edge_iterator OutEdgeItr; +// typedef boost::graph_traits< WeaveGraph >::adjacency_iterator AdjacencyItr; /// intersections between intervals are stored as a VertexPair /// pair.first is a vertex descriptor of the weave graph /// pair.second is the coordinate along the fiber of the intersection -typedef std::pair< Vertex, double > VertexPair; +typedef std::pair VertexPair; /// compare based on pair.second, the coordinate of the intersection struct VertexPairCompare { /// comparison operator - bool operator() (const VertexPair& lhs, const VertexPair& rhs) const - { return lhs.second < rhs.second ;} + bool operator()(const VertexPair &lhs, const VertexPair &rhs) const { return lhs.second < rhs.second; } }; /// intersections stored in this set (for rapid finding of neighbors etc) -typedef std::set< VertexPair, VertexPairCompare > VertexIntersectionSet; +typedef std::set VertexIntersectionSet; -typedef VertexIntersectionSet::iterator VertexPairIterator; +typedef VertexIntersectionSet::iterator VertexPairIterator; -} // end weave namespace +} // namespace weave -} // end ocl namespace +} // namespace ocl #endif // end file weave_typedef.hpp diff --git a/src/algo/zigzag.hpp b/src/algo/zigzag.hpp index 1b59fa7f..4fdb0957 100644 --- a/src/algo/zigzag.hpp +++ b/src/algo/zigzag.hpp @@ -1,104 +1,97 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef ZIGZAG_H #define ZIGZAG_H +#include #include #include #include -#include #include "point.hpp" -namespace ocl -{ +namespace ocl { /// zgizag 2D operation class ZigZag { - public: - ZigZag() { } - virtual ~ZigZag() {} - /// step over distance - void setStepOver(double d) { - stepOver = d; - } - /// set dir - void setDirection(Point d) { - dir = d; - } - void setOrigin(Point d) { - origin = d; - } - - /// run the algorithm - void run() { - // calculate a reasonable maximum/minimum step-over dist - Point perp = dir.xyPerp(); - perp.xyNormalize(); - std::cout << " minpt = " << bb.minpt << std::endl; - std::cout << " maxpt = " << bb.maxpt << std::endl; - std::cout << " perp = " << perp << std::endl; - double max_d = (bb.maxpt - origin).dot( perp ); - double min_d = (bb.minpt - origin).dot( perp ); - if ( max_d < min_d ) { - double tmp = max_d; - max_d = min_d; - min_d = tmp; - } - //int n = min_d / stepOver; // some safety margin here... (required?) - std::cout << " max_d= " << max_d << " min_d= "<< min_d << std::endl; - - std::vector distances; - for (double d = min_d ; d <= max_d ; d += stepOver ) { - distances.push_back(d); - out.push_back( origin + d*perp ); - assert( out.size() < 500 ); - } - - } - - /// add an input CLPoint to this Operation - void addPoint(Point& p) { - pocket.push_back(p); - bb.addPoint(p); + public: + ZigZag() {} + virtual ~ZigZag() {} + /// step over distance + void setStepOver(double d) { stepOver = d; } + /// set dir + void setDirection(Point d) { dir = d; } + void setOrigin(Point d) { origin = d; } + + /// run the algorithm + void run() { + // calculate a reasonable maximum/minimum step-over dist + Point perp = dir.xyPerp(); + perp.xyNormalize(); + std::cout << " minpt = " << bb.minpt << std::endl; + std::cout << " maxpt = " << bb.maxpt << std::endl; + std::cout << " perp = " << perp << std::endl; + double max_d = (bb.maxpt - origin).dot(perp); + double min_d = (bb.minpt - origin).dot(perp); + if (max_d < min_d) { + double tmp = max_d; + max_d = min_d; + min_d = tmp; } - std::string str() const { - std::ostringstream o; - o << "ZigZag: pocket.size()=" << pocket.size() << std::endl; - return o.str(); + // int n = min_d / stepOver; // some safety margin here... (required?) + std::cout << " max_d= " << max_d << " min_d= " << min_d << std::endl; + + std::vector distances; + for (double d = min_d; d <= max_d; d += stepOver) { + distances.push_back(d); + out.push_back(origin + d * perp); + assert(out.size() < 500); } - protected: - /// the step over - double stepOver; - /// direction - Point dir; - /// origin - Point origin; - /// pocket - std::vector pocket; - std::vector out; - Bbox bb; + } + + /// add an input CLPoint to this Operation + void addPoint(Point &p) { + pocket.push_back(p); + bb.addPoint(p); + } + std::string str() const { + std::ostringstream o; + o << "ZigZag: pocket.size()=" << pocket.size() << std::endl; + return o.str(); + } + + protected: + /// the step over + double stepOver; + /// direction + Point dir; + /// origin + Point origin; + /// pocket + std::vector pocket; + std::vector out; + Bbox bb; }; -} // end namespace +} // namespace ocl #endif // end zigzag.h diff --git a/src/common/brent_zero.hpp b/src/common/brent_zero.hpp index abe5a60c..b364dd16 100644 --- a/src/common/brent_zero.hpp +++ b/src/common/brent_zero.hpp @@ -1,28 +1,27 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef BRENT_ZERO_H #define BRENT_ZERO_H -namespace ocl -{ +namespace ocl { /// Brent's root finding algorithm /// http://en.wikipedia.org/wiki/Brent's_method @@ -33,95 +32,92 @@ namespace ocl /// double ErrObj::error(double x) for which we try to find a zero /// /// FIXME: describe tolerance parameters eps and t -template -double brent_zero( double a, double b, double eps, double t, ErrObj* ell) { +template double brent_zero(double a, double b, double eps, double t, ErrObj *ell) { // f must have unequal sign at a and b, i.e. // f(a)*f(b) < 0 - // returns the location of a root c where f(c)=0 - // to within 6*eps*abs(c)+2*t tolerance - double c,d,e; - double fa,fb,fc; // function values - double m,p,q,r,s; + // returns the location of a root c where f(c)=0 + // to within 6*eps*abs(c)+2*t tolerance + double c, d, e; + double fa, fb, fc; // function values + double m, p, q, r, s; double tol; - fa = ell->error(a); // f(a); - fb = ell->error(b); // f(b); - if (fa*fb >= 0.0) {// check for opposite signs + fa = ell->error(a); // f(a); + fb = ell->error(b); // f(b); + if (fa * fb >= 0.0) { // check for opposite signs std::cout << " brent_zero() called with invalid interval [a,b] !\n"; assert(0); } - c = a; // set c sln equal to a sln - fc = fa; - e = b-a; // interval width - d = e; // interval width + c = a; // set c sln equal to a sln + fc = fa; + e = b - a; // interval width + d = e; // interval width while (true) { - if (fabs(fc)b was small, or fa is a better solution - e = m; + e = m; d = e; // bisection? } else { - s = fb/fa; + s = fb / fa; if (a == c) { - p=2.0*m*s; - q=1.0-s; + p = 2.0 * m * s; + q = 1.0 - s; } else { - q = fa/fc; - r = fb/fc; - p = s*(2.0*m*a*(q-r)-(b-a)*(r-1.0)); - q = (q-1.0)*(r-1.0)*(s-1.0); + q = fa / fc; + r = fb / fc; + p = s * (2.0 * m * a * (q - r) - (b - a) * (r - 1.0)); + q = (q - 1.0) * (r - 1.0) * (s - 1.0); } - - if (p>0.0) - q=-q; + + if (p > 0.0) + q = -q; else - p=-p; // make p negative - - s=e; - e=d; - if ( (2.0*p < (3.0*m*q-fabs(tol*q))) && (p tol ) // if d is "large" - b = b+d; // push the root by d - else if ( m > 0.0 ) - b = b+tol; // otherwise, push root by tol in direction of m + if (fabs(d) > tol) // if d is "large" + b = b + d; // push the root by d + else if (m > 0.0) + b = b + tol; // otherwise, push root by tol in direction of m else - b = b-tol; + b = b - tol; // std::cout << " brent_zero b=" << b << "\n"; - + fb = ell->error(b); // f(b); - - if ( ((fb>0.0) && (fc>0.0)) || ((fb<=0.0) && (fc<=0.0)) ) { + + if (((fb > 0.0) && (fc > 0.0)) || ((fb <= 0.0) && (fc <= 0.0))) { // fb and fc have the same sign - c = a; // so change c to a + c = a; // so change c to a fc = fa; - e = b-a; // interval width + e = b - a; // interval width d = e; } } // end iteration-loop return b; } - - -} // end namespace +} // namespace ocl #endif // end file brent_zero.hpp diff --git a/src/common/clfilter.hpp b/src/common/clfilter.hpp index d80ad85e..b477d2f1 100644 --- a/src/common/clfilter.hpp +++ b/src/common/clfilter.hpp @@ -1,59 +1,58 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef CLFILTER_H #define CLFILTER_H #include -#include #include +#include #include "clpoint.hpp" -namespace ocl -{ +namespace ocl { /// /// \brief CL point filter virtual base class /// -class CLFilter { - public: - /// constructor - CLFilter() {} ; - virtual ~CLFilter() {}; - - /// add CLPoint - virtual void addCLPoint(const CLPoint& p) = 0; - /// set the tolerance value - virtual void setTolerance(const double tol) = 0; - - /// run filter - virtual void run() = 0; - - /// the list of CL-points to be processed - std::list clpoints; - /// tolerance - double tol; +class CLFilter { + public: + /// constructor + CLFilter(){}; + virtual ~CLFilter(){}; + + /// add CLPoint + virtual void addCLPoint(const CLPoint &p) = 0; + /// set the tolerance value + virtual void setTolerance(const double tol) = 0; + + /// run filter + virtual void run() = 0; + + /// the list of CL-points to be processed + std::list clpoints; + /// tolerance + double tol; }; -} // end namespace +} // namespace ocl #endif // end file clfilter.h diff --git a/src/common/halfedgediagram.hpp b/src/common/halfedgediagram.hpp index 33d5ff7d..56766a90 100644 --- a/src/common/halfedgediagram.hpp +++ b/src/common/halfedgediagram.hpp @@ -1,31 +1,31 @@ /* $Id$ - * + * * Copyright (c) 2010-2011 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef HALFEDGEDIAGRAM_HPP #define HALFEDGEDIAGRAM_HPP -#include #include +#include +#include #include -#include // bundled BGL properties, see: http://www.boost.org/doc/libs/1_44_0/libs/graph/doc/bundles.html @@ -51,12 +51,11 @@ // special "infinite face", face on "outside" of boundary // may or may not store edge pointer - /// HEDIGraph is a A half-edge diagram class. /// Templated on Vertex/Edge/Face property classes which allow -/// attaching information to vertices/edges/faces that is +/// attaching information to vertices/edges/faces that is /// required for a particular algorithm. -/// +/// /// Inherits from boost::adjacency_list /// minor additions allow storing face-properties. /// @@ -68,393 +67,345 @@ namespace ocl { -namespace hedi { - -template +namespace hedi { + +template class HEDIGraph { - public: - - typedef typename boost::adjacency_list< TOutEdgeList, - TVertexList, - TDirected, - TVertexProperties, - TEdgeProperties, - TGraphProperties, - TEdgeList - > BGLGraph; - typedef unsigned int Face; - typedef typename boost::graph_traits< BGLGraph >::edge_descriptor Edge; - typedef typename boost::graph_traits< BGLGraph >::vertex_descriptor Vertex; - typedef typename boost::graph_traits< BGLGraph >::vertex_iterator VertexItr; - typedef typename boost::graph_traits< BGLGraph >::edge_iterator EdgeItr; - typedef typename boost::graph_traits< BGLGraph >::out_edge_iterator OutEdgeItr; - typedef typename boost::graph_traits< BGLGraph >::adjacency_iterator AdjacencyItr; - - typedef std::vector VertexVector; - typedef std::vector FaceVector; - typedef std::vector EdgeVector; - - inline TFaceProperties& operator[](Face f) { return faces[f]; } - inline const TFaceProperties& operator[](Face f) const { return faces[f]; } - - inline TEdgeProperties& operator[](Edge e) { return g[e]; } - inline const TEdgeProperties& operator[](Edge e) const { return g[e]; } - - inline TVertexProperties& operator[](Vertex v) { return g[v]; } - inline const TVertexProperties& operator[](Vertex v) const { return g[v]; } - -//DATA - std::vector< TFaceProperties > faces; - BGLGraph g; - -Vertex null_vertex() { - return boost::graph_traits::null_vertex(); -} - -/// add a blank vertex and return its descriptor -Vertex add_vertex() { - return boost::add_vertex( g ); -} - -/* -/// add a vertex with given properties, return vertex descriptor -template < class FVertexProperty> -typename boost::graph_traits< BGLGraph >::vertex_descriptor add_vertex(typedef const FVertexProperty& prop) { - return boost::add_vertex( prop, g ); -}*/ - -/// add an edge between vertices v1-v2 -Edge add_edge(Vertex v1, Vertex v2) { - Edge e; - bool b; - boost::tie( e , b ) = boost::add_edge( v1, v2, g); - return e; -} - -/// add an edge with given properties between vertices v1-v2 -//template < class EdgeProperty> -/* -typename boost::graph_traits< BGLGraph >::edge_descriptor add_edge( - typename boost::graph_traits< BGLGraph >::vertex_descriptor v1, - typename boost::graph_traits< BGLGraph >::vertex_descriptor v2, - typename TEdgeProperties prop - ) { - typename boost::graph_traits< BGLGraph >::edge_descriptor e; - bool b; - boost::tie( e , b ) = boost::add_edge( v1, v2, prop, g); - return e; -}*/ - -/// make e1 the twin of e2 (and vice versa) -void twin_edges( Edge e1, Edge e2 ) { - g[e1].twin = e2; - g[e2].twin = e1; -} - - -/// add a face -Face add_face() { - TFaceProperties f_prop; - faces.push_back( f_prop); - Face index = faces.size()-1; - faces[index].idx = index; - return index; -} - - -/// return the target vertex of the given edge -Vertex target( Edge e ) { - return boost::target( e, g); -} - -/// return the source vertex of the given edge -Vertex source( Edge e ) { - return boost::source( e, g); -} - -/// return all vertices in a vector of vertex descriptors -VertexVector vertices() { - typedef typename boost::graph_traits< BGLGraph >::vertex_descriptor HEVertex; - typedef std::vector VertexVector; - typedef typename boost::graph_traits< BGLGraph >::vertex_iterator HEVertexItr; - VertexVector vv; - HEVertexItr it_begin, it_end, itr; - boost::tie( it_begin, it_end ) = boost::vertices( g ); - for ( itr=it_begin ; itr != it_end ; ++itr ) { - vv.push_back( *itr ); + public: + typedef typename boost::adjacency_list + BGLGraph; + typedef unsigned int Face; + typedef typename boost::graph_traits::edge_descriptor Edge; + typedef typename boost::graph_traits::vertex_descriptor Vertex; + typedef typename boost::graph_traits::vertex_iterator VertexItr; + typedef typename boost::graph_traits::edge_iterator EdgeItr; + typedef typename boost::graph_traits::out_edge_iterator OutEdgeItr; + typedef typename boost::graph_traits::adjacency_iterator AdjacencyItr; + + typedef std::vector VertexVector; + typedef std::vector FaceVector; + typedef std::vector EdgeVector; + + inline TFaceProperties &operator[](Face f) { return faces[f]; } + inline const TFaceProperties &operator[](Face f) const { return faces[f]; } + + inline TEdgeProperties &operator[](Edge e) { return g[e]; } + inline const TEdgeProperties &operator[](Edge e) const { return g[e]; } + + inline TVertexProperties &operator[](Vertex v) { return g[v]; } + inline const TVertexProperties &operator[](Vertex v) const { return g[v]; } + + // DATA + std::vector faces; + BGLGraph g; + + Vertex null_vertex() { return boost::graph_traits::null_vertex(); } + + /// add a blank vertex and return its descriptor + Vertex add_vertex() { return boost::add_vertex(g); } + + /* + /// add a vertex with given properties, return vertex descriptor + template < class FVertexProperty> + typename boost::graph_traits< BGLGraph >::vertex_descriptor add_vertex(typedef const FVertexProperty& prop) { + return boost::add_vertex( prop, g ); + }*/ + + /// add an edge between vertices v1-v2 + Edge add_edge(Vertex v1, Vertex v2) { + Edge e; + bool b; + boost::tie(e, b) = boost::add_edge(v1, v2, g); + return e; } - return vv; -} - -/// return all vertices adjecent to given vertex -VertexVector adjacent_vertices( Vertex v) { - VertexVector vv; - BOOST_FOREACH( Edge edge, out_edges( v ) ) { - vv.push_back( target( edge ) ); + + /// add an edge with given properties between vertices v1-v2 + // template < class EdgeProperty> + /* + typename boost::graph_traits< BGLGraph >::edge_descriptor add_edge( + typename boost::graph_traits< BGLGraph >::vertex_descriptor + v1, typename boost::graph_traits< BGLGraph >::vertex_descriptor v2, typename TEdgeProperties prop ) { typename + boost::graph_traits< BGLGraph >::edge_descriptor e; bool b; boost::tie( e , b ) = boost::add_edge( v1, v2, prop, g); + return e; + }*/ + + /// make e1 the twin of e2 (and vice versa) + void twin_edges(Edge e1, Edge e2) { + g[e1].twin = e2; + g[e2].twin = e1; } - return vv; -} - -/// return all vertices of given face - -VertexVector face_vertices(Face face_idx) { - VertexVector verts; - Edge startedge = faces[face_idx].edge; // the edge where we start - Vertex start_target = boost::target( startedge, g); - verts.push_back(start_target); - Edge current = g[startedge].next; - do { - Vertex current_target = boost::target( current, g); - verts.push_back(current_target); - current = g[current].next; - } while ( current != startedge ); - return verts; -} - -/// return edges of face f -EdgeVector face_edges( Face f ) { - //Edge start_edge = g[ f ].edge; // was cast: (Face)f - Edge start_edge = faces[f].edge; - Edge current_edge = start_edge; - EdgeVector out; - do { - out.push_back(current_edge); - current_edge = g[current_edge].next; - } while( current_edge != start_edge ); - return out; -} - - -/// return degree of given vertex -unsigned int degree( Vertex v) { - return boost::degree( v, g); -} - -/// return number of vertices in graph -unsigned int num_vertices() const { - return static_cast(boost::num_vertices( g )); -} - -/// return out_edges of given vertex -EdgeVector out_edges( Vertex v) { - typedef typename boost::graph_traits< BGLGraph >::out_edge_iterator HEOutEdgeItr; - EdgeVector ev; - HEOutEdgeItr it, it_end; - boost::tie( it, it_end ) = boost::out_edges( v, g ); - for ( ; it != it_end ; ++it ) { - ev.push_back(*it); + + /// add a face + Face add_face() { + TFaceProperties f_prop; + faces.push_back(f_prop); + Face index = faces.size() - 1; + faces[index].idx = index; + return index; } - return ev; -} - -/// return all edges -EdgeVector edges() { - typedef typename boost::graph_traits< BGLGraph >::edge_iterator HEEdgeItr; - EdgeVector ev; - HEEdgeItr it, it_end; - boost::tie( it, it_end ) = boost::edges( g ); - for ( ; it != it_end ; ++it ) { - ev.push_back(*it); + + /// return the target vertex of the given edge + Vertex target(Edge e) { return boost::target(e, g); } + + /// return the source vertex of the given edge + Vertex source(Edge e) { return boost::source(e, g); } + + /// return all vertices in a vector of vertex descriptors + VertexVector vertices() { + typedef typename boost::graph_traits::vertex_descriptor HEVertex; + typedef std::vector VertexVector; + typedef typename boost::graph_traits::vertex_iterator HEVertexItr; + VertexVector vv; + HEVertexItr it_begin, it_end, itr; + boost::tie(it_begin, it_end) = boost::vertices(g); + for (itr = it_begin; itr != it_end; ++itr) { + vv.push_back(*itr); + } + return vv; } - return ev; -} - -/// return v1-v2 edge descriptor -Edge edge( Vertex v1, Vertex v2 ) { - typedef typename std::pair EdgeBool; - EdgeBool result = boost::edge(v1, v2, g ); - return result.first; -} - -/// return the previous edge. traverses all edges in face until previous found. -Edge previous_edge( Edge e ) { - Edge previous = g[e].next; - while ( g[previous].next != e ) { - previous = g[previous].next; + + /// return all vertices adjecent to given vertex + VertexVector adjacent_vertices(Vertex v) { + VertexVector vv; + BOOST_FOREACH (Edge edge, out_edges(v)) { + vv.push_back(target(edge)); + } + return vv; } - return previous; -} - - -/// return true if v1-v2 edge exists -bool has_edge( Vertex v1, Vertex v2) { - typedef typename std::pair EdgeBool; - EdgeBool result = boost::edge(v1, v2, g ); - return result.second; -} - -/// return adjacent faces to the given vertex -FaceVector adjacent_faces( Vertex q ) { - typedef typename boost::graph_traits< BGLGraph >::out_edge_iterator HEOutEdgeItr; - std::set face_set; - HEOutEdgeItr itr, itr_end; - boost::tie( itr, itr_end) = boost::out_edges(q, g); - for ( ; itr!=itr_end ; ++itr ) { - face_set.insert( g[*itr].face ); + + /// return all vertices of given face + + VertexVector face_vertices(Face face_idx) { + VertexVector verts; + Edge startedge = faces[face_idx].edge; // the edge where we start + Vertex start_target = boost::target(startedge, g); + verts.push_back(start_target); + Edge current = g[startedge].next; + do { + Vertex current_target = boost::target(current, g); + verts.push_back(current_target); + current = g[current].next; + } while (current != startedge); + return verts; + } + + /// return edges of face f + EdgeVector face_edges(Face f) { + // Edge start_edge = g[ f ].edge; // was cast: (Face)f + Edge start_edge = faces[f].edge; + Edge current_edge = start_edge; + EdgeVector out; + do { + out.push_back(current_edge); + current_edge = g[current_edge].next; + } while (current_edge != start_edge); + return out; + } + + /// return degree of given vertex + unsigned int degree(Vertex v) { return boost::degree(v, g); } + + /// return number of vertices in graph + unsigned int num_vertices() const { return static_cast(boost::num_vertices(g)); } + + /// return out_edges of given vertex + EdgeVector out_edges(Vertex v) { + typedef typename boost::graph_traits::out_edge_iterator HEOutEdgeItr; + EdgeVector ev; + HEOutEdgeItr it, it_end; + boost::tie(it, it_end) = boost::out_edges(v, g); + for (; it != it_end; ++it) { + ev.push_back(*it); + } + return ev; + } + + /// return all edges + EdgeVector edges() { + typedef typename boost::graph_traits::edge_iterator HEEdgeItr; + EdgeVector ev; + HEEdgeItr it, it_end; + boost::tie(it, it_end) = boost::edges(g); + for (; it != it_end; ++it) { + ev.push_back(*it); + } + return ev; } - FaceVector fv; - BOOST_FOREACH(unsigned int m, face_set) { - fv.push_back(m); + + /// return v1-v2 edge descriptor + Edge edge(Vertex v1, Vertex v2) { + typedef typename std::pair EdgeBool; + EdgeBool result = boost::edge(v1, v2, g); + return result.first; } - return fv; -} - -/// return number of faces in graph -unsigned int num_faces() const { - return faces.size(); -} - -/// return number of edges in graph -unsigned int num_edges() const { - return static_cast(boost::num_edges( g )); -} - -/// inserts given vertex into edge e, and into the twin edge e_twin -void insert_vertex_in_edge(Vertex v, Edge e ) { - // the vertex v is in the middle of edge e - // face - // e1 e2 - // previous-> source -> v -> target -> next - // tw_trg <- v <- tw_src <- tw_previous - // te2 te1 - // twin_face - - Edge twin = g[e].twin; - Vertex source = boost::source( e , g ); - Vertex target = boost::target( e , g); - Vertex twin_source = boost::source( twin , g); - Vertex twin_target = boost::target( twin , g ); - assert( source == twin_target ); - assert( target == twin_source ); - - Face face = g[e].face; - Face twin_face = g[twin].face; - Edge previous = previous_edge(e); - assert( g[previous].face == g[e].face ); - Edge twin_previous = previous_edge(twin); - assert( g[twin_previous].face == g[twin].face ); - - Edge e1 = add_edge( source, v ); - Edge e2 = add_edge( v, target ); - - // preserve the left/right face link - g[e1].face = face; - g[e2].face = face; - // next-pointers - g[previous].next = e1; - g[e1].next = e2; - g[e2].next = g[e].next; - - - Edge te1 = add_edge( twin_source, v ); - Edge te2 = add_edge( v, twin_target ); - - g[te1].face = twin_face; - g[te2].face = twin_face; - - g[twin_previous].next = te1; - g[te1].next = te2; - g[te2].next = g[twin].next; - - // TWINNING (note indices 'cross', see ASCII art above) - g[e1].twin = te2; - g[te2].twin = e1; - g[e2].twin = te1; - g[te1].twin = e2; - - // update the faces (required here?) - faces[face].edge = e1; - faces[twin_face].edge = te1; - - // finally, remove the old edge - boost::remove_edge( e , g); - boost::remove_edge( twin, g); -} - - -/// inserts given vertex into edge e -/* -template -void insert_vertex_in_half_edge(typename boost::graph_traits< BGLGraph >::vertex_descriptor v, - typename boost::graph_traits< BGLGraph >::edge_descriptor e, - BGLGraph& g) { - typedef typename boost::graph_traits< BGLGraph >::edge_descriptor HEEdge; - typedef typename boost::graph_traits< BGLGraph >::vertex_descriptor HEVertex; - // the vertex v is in the middle of edge e - // face - // e1 e2 - // previous-> source -> v -> target -> next - - HEVertex source = boost::source( e , g ); - HEVertex target = boost::target( e , g); - unsigned int face = g[e].face; - HEEdge previous = previous_edge(e, g); - assert( g[previous].face == g[e].face ); - HEEdge e1 = add_edge( source, v , g); - HEEdge e2 = add_edge( v, target , g); - // preserve the left/right face link - g[e1].face = face; - g[e2].face = face; - // next-pointers - g[previous].next = e1; - g[e1].next = e2; - g[e2].next = g[e].next; - // update the faces (required here?) - g.faces[face].edge = e1; - // finally, remove the old edge - boost::remove_edge( e , g); - // NOTE: twinning is not done here, since the twin edge is not split... -} - -*/ - /// check that all edges belong to the correct face, TODO: template this to make it a useful check - /* - bool checkFaces() { - BOOST_FOREACH(FaceProps f, faces) { - BOOST_FOREACH( HEEdge e, face_edges(f.idx)) { - if ( g[e].face != f.idx ) - return false; - } + + /// return the previous edge. traverses all edges in face until previous found. + Edge previous_edge(Edge e) { + Edge previous = g[e].next; + while (g[previous].next != e) { + previous = g[previous].next; + } + return previous; + } + + /// return true if v1-v2 edge exists + bool has_edge(Vertex v1, Vertex v2) { + typedef typename std::pair EdgeBool; + EdgeBool result = boost::edge(v1, v2, g); + return result.second; + } + + /// return adjacent faces to the given vertex + FaceVector adjacent_faces(Vertex q) { + typedef typename boost::graph_traits::out_edge_iterator HEOutEdgeItr; + std::set face_set; + HEOutEdgeItr itr, itr_end; + boost::tie(itr, itr_end) = boost::out_edges(q, g); + for (; itr != itr_end; ++itr) { + face_set.insert(g[*itr].face); + } + FaceVector fv; + BOOST_FOREACH (unsigned int m, face_set) { + fv.push_back(m); + } + return fv; + } + + /// return number of faces in graph + unsigned int num_faces() const { return faces.size(); } + + /// return number of edges in graph + unsigned int num_edges() const { return static_cast(boost::num_edges(g)); } + + /// inserts given vertex into edge e, and into the twin edge e_twin + void insert_vertex_in_edge(Vertex v, Edge e) { + // the vertex v is in the middle of edge e + // face + // e1 e2 + // previous-> source -> v -> target -> next + // tw_trg <- v <- tw_src <- tw_previous + // te2 te1 + // twin_face + + Edge twin = g[e].twin; + Vertex source = boost::source(e, g); + Vertex target = boost::target(e, g); + Vertex twin_source = boost::source(twin, g); + Vertex twin_target = boost::target(twin, g); + assert(source == twin_target); + assert(target == twin_source); + + Face face = g[e].face; + Face twin_face = g[twin].face; + Edge previous = previous_edge(e); + assert(g[previous].face == g[e].face); + Edge twin_previous = previous_edge(twin); + assert(g[twin_previous].face == g[twin].face); + + Edge e1 = add_edge(source, v); + Edge e2 = add_edge(v, target); + + // preserve the left/right face link + g[e1].face = face; + g[e2].face = face; + // next-pointers + g[previous].next = e1; + g[e1].next = e2; + g[e2].next = g[e].next; + + Edge te1 = add_edge(twin_source, v); + Edge te2 = add_edge(v, twin_target); + + g[te1].face = twin_face; + g[te2].face = twin_face; + + g[twin_previous].next = te1; + g[te1].next = te2; + g[te2].next = g[twin].next; + + // TWINNING (note indices 'cross', see ASCII art above) + g[e1].twin = te2; + g[te2].twin = e1; + g[e2].twin = te1; + g[te1].twin = e2; + + // update the faces (required here?) + faces[face].edge = e1; + faces[twin_face].edge = te1; + + // finally, remove the old edge + boost::remove_edge(e, g); + boost::remove_edge(twin, g); + } + + /// inserts given vertex into edge e + /* + template + void insert_vertex_in_half_edge(typename boost::graph_traits< BGLGraph >::vertex_descriptor v, + typename boost::graph_traits< BGLGraph >::edge_descriptor e, + BGLGraph& g) { + typedef typename boost::graph_traits< BGLGraph >::edge_descriptor HEEdge; + typedef typename boost::graph_traits< BGLGraph >::vertex_descriptor HEVertex; + // the vertex v is in the middle of edge e + // face + // e1 e2 + // previous-> source -> v -> target -> next + + HEVertex source = boost::source( e , g ); + HEVertex target = boost::target( e , g); + unsigned int face = g[e].face; + HEEdge previous = previous_edge(e, g); + assert( g[previous].face == g[e].face ); + HEEdge e1 = add_edge( source, v , g); + HEEdge e2 = add_edge( v, target , g); + // preserve the left/right face link + g[e1].face = face; + g[e2].face = face; + // next-pointers + g[previous].next = e1; + g[e1].next = e2; + g[e2].next = g[e].next; + // update the faces (required here?) + g.faces[face].edge = e1; + // finally, remove the old edge + boost::remove_edge( e , g); + // NOTE: twinning is not done here, since the twin edge is not split... + } + + */ + /// check that all edges belong to the correct face, TODO: template this to make it a useful check + /* + bool checkFaces() { + BOOST_FOREACH(FaceProps f, faces) { + BOOST_FOREACH( HEEdge e, face_edges(f.idx)) { + if ( g[e].face != f.idx ) + return false; } - return true; - }*/ - -/// delete a vertex -void delete_vertex(Vertex v) { - clear_vertex(v); - remove_vertex(v); -} - -/// clear given vertex. this removes all edges connecting to the vertex. -void clear_vertex( Vertex v) { - boost::clear_vertex( v, g ); -} -/// remove given vertex -void remove_vertex( Vertex v) { - boost::remove_vertex( v , g ); -} - -void remove_edge( Vertex v1, Vertex v2) { - boost::remove_edge( v1, v2 , g); -} - -void remove_edge( Edge e) { - boost::remove_edge( e , g); -} + } + return true; + }*/ + + /// delete a vertex + void delete_vertex(Vertex v) { + clear_vertex(v); + remove_vertex(v); + } -}; // end class definition + /// clear given vertex. this removes all edges connecting to the vertex. + void clear_vertex(Vertex v) { boost::clear_vertex(v, g); } + /// remove given vertex + void remove_vertex(Vertex v) { boost::remove_vertex(v, g); } + + void remove_edge(Vertex v1, Vertex v2) { boost::remove_edge(v1, v2, g); } + void remove_edge(Edge e) { boost::remove_edge(e, g); } + +}; // end class definition -} // end hedi namespace +} // namespace hedi -} // end ocl namespace +} // namespace ocl #endif // end halfedgediagram.hpp diff --git a/src/common/kdnode.hpp b/src/common/kdnode.hpp index 28e8521b..28ecdc9f 100644 --- a/src/common/kdnode.hpp +++ b/src/common/kdnode.hpp @@ -1,23 +1,23 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef KDNODE_H #define KDNODE_H @@ -27,80 +27,77 @@ #include -namespace ocl -{ - +namespace ocl { + /// \brief K-D tree node. http://en.wikipedia.org/wiki/Kd-tree /// /// A k-d tree is used for searching for triangles overlapping with the cutter. /// -template < class BBObj > -class KDNode { - public: - /// Create a node which partitions(cuts) along dimension d, at - /// cut value cv, with child-nodes hi_c and lo_c. - /// If this is a bucket-node containing triangles, - /// they are in the list tris - /// depth indicates the depth of the node in the tree - KDNode(int d, double cv, KDNode *parentNode, // parent node - KDNode *hi_child, // hi-child - KDNode *lo_child, // lo-child - const std::list< BBObj >* tlist, // list of tris, if bucket - int nodeDepth) // depth of node - { - dim = d; - cutval = cv; - parent = parentNode; - hi = hi_child; - lo = lo_child; - tris = new std::list(); - depth = nodeDepth; - isLeaf = false; - if (tlist) { - isLeaf = true; - BOOST_FOREACH(BBObj bo, *tlist) { - tris->push_back(bo); - } +template class KDNode { + public: + /// Create a node which partitions(cuts) along dimension d, at + /// cut value cv, with child-nodes hi_c and lo_c. + /// If this is a bucket-node containing triangles, + /// they are in the list tris + /// depth indicates the depth of the node in the tree + KDNode(int d, double cv, KDNode *parentNode, // parent node + KDNode *hi_child, // hi-child + KDNode *lo_child, // lo-child + const std::list *tlist, // list of tris, if bucket + int nodeDepth) // depth of node + { + dim = d; + cutval = cv; + parent = parentNode; + hi = hi_child; + lo = lo_child; + tris = new std::list(); + depth = nodeDepth; + isLeaf = false; + if (tlist) { + isLeaf = true; + BOOST_FOREACH (BBObj bo, *tlist) { + tris->push_back(bo); } } - virtual ~KDNode() { - // std::cout << " ~KDNode3()\n"; - if (hi) - delete hi; - if (lo) - delete lo; - if (tris) - delete tris; - } - /// string repr - std::string str() const { - std::ostringstream o; - o << "KDNode d:" << dim << " cv:" << cutval; - return o.str(); - } - + } + virtual ~KDNode() { + // std::cout << " ~KDNode3()\n"; + if (hi) + delete hi; + if (lo) + delete lo; + if (tris) + delete tris; + } + /// string repr + std::string str() const { + std::ostringstream o; + o << "KDNode d:" << dim << " cv:" << cutval; + return o.str(); + } + // DATA - /// level of node in tree - int depth; - /// dimension of cut - int dim; - /// Cut value. - /// Child node hi contains only triangles with a higher value than this. - /// Child node lo contains triangles with lower values. - double cutval; - /// parent-node - KDNode* parent; - /// Child-node hi. - KDNode* hi; - /// Child-node lo. - KDNode* lo; - /// A list of triangles, if this is a bucket-node (NULL for internal nodes) - std::list< BBObj >* tris; - /// flag to indicate leaf in the tree. Leafs or bucket-nodes contain triangles in the list tris. - bool isLeaf; + /// level of node in tree + int depth; + /// dimension of cut + int dim; + /// Cut value. + /// Child node hi contains only triangles with a higher value than this. + /// Child node lo contains triangles with lower values. + double cutval; + /// parent-node + KDNode *parent; + /// Child-node hi. + KDNode *hi; + /// Child-node lo. + KDNode *lo; + /// A list of triangles, if this is a bucket-node (NULL for internal nodes) + std::list *tris; + /// flag to indicate leaf in the tree. Leafs or bucket-nodes contain triangles in the list tris. + bool isLeaf; }; - -} // end namespace +} // namespace ocl #endif // end file kdnode.h diff --git a/src/common/kdtree.hpp b/src/common/kdtree.hpp index 97b8f8be..03ba4ce6 100644 --- a/src/common/kdtree.hpp +++ b/src/common/kdtree.hpp @@ -1,23 +1,23 @@ /* $Id$ - * + * * Copyright (c) 2010-2011 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef KDTREE_H #define KDTREE_H @@ -27,15 +27,14 @@ #include -#include "kdnode.hpp" #include "bbox.hpp" -#include "millingcutter.hpp" #include "clpoint.hpp" +#include "kdnode.hpp" +#include "millingcutter.hpp" #include "numeric.hpp" -namespace ocl -{ - +namespace ocl { + class Point; class CLPoint; class Triangle; @@ -43,261 +42,256 @@ class MillingCutter; /// \brief KDTree spread, a measure of how spread-out a list of triangles are. /// -/// simple struct-like class for storing the "spread" or maximum +/// simple struct-like class for storing the "spread" or maximum /// extent of a list of triangles. Used by the kd-tree algorithm. class Spread { - public: - /// constructor - Spread(int dim, double v, double s) { - d = dim; - val = v; - start = s; - }; - /// dimension - int d; - /// spread-value - double val; - /// minimum or start value - double start; - /// comparison of Spread objects. Used for finding the largest spread - /// along which the next partition/cut is made. - static bool spread_compare(Spread *x, Spread *y) { - if (x->val > y->val) - return true; - else - return false; - }; + public: + /// constructor + Spread(int dim, double v, double s) { + d = dim; + val = v; + start = s; + }; + /// dimension + int d; + /// spread-value + double val; + /// minimum or start value + double start; + /// comparison of Spread objects. Used for finding the largest spread + /// along which the next partition/cut is made. + static bool spread_compare(Spread *x, Spread *y) { + if (x->val > y->val) + return true; + else + return false; + }; }; /// a kd-tree for storing triangles and fast searching for triangles /// that overlap the cutter -template -class KDTree { - public: - KDTree() { - root = nullptr; - } - virtual ~KDTree() { - // std::cout << " ~KDTree()" << std::endl; - delete root; - } - /// set the bucket-size - void setBucketSize(int b){ - //std::cout << "KDTree::setBucketSize = " << b << "\n"; - bucketSize = b; +template class KDTree { + public: + KDTree() { root = nullptr; } + virtual ~KDTree() { + // std::cout << " ~KDTree()" << std::endl; + delete root; + } + /// set the bucket-size + void setBucketSize(int b) { + // std::cout << "KDTree::setBucketSize = " << b << "\n"; + bucketSize = b; + } + /// set the search dimension to the XY-plane + void setXYDimensions() { + // std::cout << "KDTree::setXYDimensions()\n"; + dimensions.clear(); + dimensions.push_back(0); // x + dimensions.push_back(1); // x + dimensions.push_back(2); // y + dimensions.push_back(3); // y + } // for drop-cutter search in XY plane + /// set search-plane to YZ + void setYZDimensions() { // for X-fibers + // std::cout << "KDTree::setYZDimensions()\n"; + dimensions.clear(); + dimensions.push_back(2); // y + dimensions.push_back(3); // y + dimensions.push_back(4); // z + dimensions.push_back(5); // z + } // for X-fibers + /// set search plane to XZ + void setXZDimensions() { // for Y-fibers + // std::cout << "KDTree::setXZDimensions()\n"; + dimensions.clear(); + dimensions.push_back(0); // x + dimensions.push_back(1); // x + dimensions.push_back(4); // z + dimensions.push_back(5); // z + } // for Y-fibers + /// build the kd-tree based on a list of input objects + void build(const std::list &list) { + // std::cout << "KDTree::build() list.size()= " << list.size() << " \n"; + delete root; + root = build_node(&list, 0, NULL); + } + /// search for overlap with input Bbox bb, return found objects + std::list *search(const Bbox &bb) { + assert(!dimensions.empty()); + std::list *tris = new std::list(); + this->search_node(tris, bb, root); + return tris; + } + /// search for overlap with a MillingCutter c positioned at cl, return found objects + std::list *search_cutter_overlap(const MillingCutter *c, CLPoint *cl) { + double r = c->getRadius(); + // build a bounding-box at the current CL + Bbox bb(cl->x - r, cl->x + r, cl->y - r, cl->y + r, cl->z, cl->z + c->getLength()); + return this->search(bb); + } + /// string repr + std::string str() const; + + protected: + /// build and return a KDNode containing list *tris at depth dep. + KDNode *build_node(const std::list *tris, // triangles + int dep, // depth of node + KDNode *par) { // parent node + // std::cout << "KDNode::build_node list.size()=" << tris->size() << "\n"; + + if (tris->size() == 0) { // this is a fatal error. + std::cout << "ERROR: KDTree::build_node() called with tris->size()==0 ! \n"; + assert(0); + return 0; } - /// set the search dimension to the XY-plane - void setXYDimensions(){ - //std::cout << "KDTree::setXYDimensions()\n"; - dimensions.clear(); - dimensions.push_back(0); // x - dimensions.push_back(1); // x - dimensions.push_back(2); // y - dimensions.push_back(3); // y - } // for drop-cutter search in XY plane - /// set search-plane to YZ - void setYZDimensions(){ // for X-fibers - //std::cout << "KDTree::setYZDimensions()\n"; - dimensions.clear(); - dimensions.push_back(2); // y - dimensions.push_back(3); // y - dimensions.push_back(4); // z - dimensions.push_back(5); // z - } // for X-fibers - /// set search plane to XZ - void setXZDimensions(){ // for Y-fibers - //std::cout << "KDTree::setXZDimensions()\n"; - dimensions.clear(); - dimensions.push_back(0); // x - dimensions.push_back(1); // x - dimensions.push_back(4); // z - dimensions.push_back(5); // z - } // for Y-fibers - /// build the kd-tree based on a list of input objects - void build(const std::list& list){ - //std::cout << "KDTree::build() list.size()= " << list.size() << " \n"; - delete root; - root = build_node( &list, 0, NULL ); + Spread *spr = calc_spread(tris); // calculate spread in order to know how to cut + double cutvalue = spr->start + spr->val / 2; // cut in the middle + // std::cout << " cutvalue= " << cutvalue << "\n"; + if ((tris->size() <= bucketSize) || isZero_tol(spr->val)) { // then return a bucket/leaf node + // std::cout << "KDNode::build_node BUCKET list.size()=" << tris->size() << "\n"; + KDNode *bucket; // dim cutv parent hi lo triangles depth + bucket = new KDNode(spr->d, cutvalue, par, NULL, NULL, tris, dep); + assert(bucket->isLeaf); + delete spr; + return bucket; // this is the leaf/end of the recursion-tree } - /// search for overlap with input Bbox bb, return found objects - std::list* search( const Bbox& bb ){ - assert( !dimensions.empty() ); - std::list* tris = new std::list(); - this->search_node( tris, bb, root ); - return tris; + // build lists of triangles for hi and lo child nodes + std::list *lolist = new std::list(); + std::list *hilist = new std::list(); + BOOST_FOREACH (BBObj t, *tris) { // loop through each triangle and put it in either lolist or hilist + if (t.bb[spr->d] > cutvalue) + hilist->push_back(t); + else + lolist->push_back(t); } - /// search for overlap with a MillingCutter c positioned at cl, return found objects - std::list* search_cutter_overlap(const MillingCutter* c, CLPoint* cl ){ - double r = c->getRadius(); - // build a bounding-box at the current CL - Bbox bb( cl->x-r, cl->x+r, cl->y-r, cl->y+r, cl->z, cl->z+c->getLength() ); - return this->search( bb ); + + /* + if (hilist->empty() || lolist->empty()) {// an error ?? + std::cout << "kdtree: hilist.size()==0! or lolist.size()==0! \n"; + std::cout << "kdtree: tris->size()= " << tris->size()<< "\n"; + std::cout << "kdtree: hilist.size()= " << hilist->size()<< "\n"; + std::cout << "kdtree: lolist.size()= " << lolist->size()<< "\n"; + BOOST_FOREACH(BBObj t, *tris) { + std::cout << t << "\n"; + std::cout << t.bb << "\n"; + } + std::cout << "kdtree: spr->d= " << spr->d << "\n"; + std::cout << "kdtree: cutvalue= " << cutvalue << "\n"; + assert(0); + }*/ + + // create the current node dim value parent hi lo trilist depth + KDNode *node = new KDNode(spr->d, cutvalue, par, NULL, NULL, NULL, dep); + // create the child-nodes through recursion + // list depth parent + if (!hilist->empty()) + node->hi = build_node(hilist, dep + 1, node); + // else + // std::cout << "hilist empty!\n"; + + if (!lolist->empty()) { + node->lo = build_node(lolist, dep + 1, node); + } else { + // std::cout << "lolist empty!\n"; } - /// string repr - std::string str() const; - - protected: - /// build and return a KDNode containing list *tris at depth dep. - KDNode* build_node( const std::list *tris, // triangles - int dep, // depth of node - KDNode *par) { // parent node - //std::cout << "KDNode::build_node list.size()=" << tris->size() << "\n"; - - if (tris->size() == 0 ) { //this is a fatal error. - std::cout << "ERROR: KDTree::build_node() called with tris->size()==0 ! \n"; - assert(0); - return 0; + + lolist->clear(); + hilist->clear(); + delete spr; + delete lolist; + delete hilist; + + return node; // return a new node + }; + + /// calculate the spread of list *tris + Spread *calc_spread(const std::list *tris) { + std::vector maxval(6); + std::vector minval(6); + if (tris->empty()) { + std::cout << " ERROR, KDTree::calc_spread() called with tris->size()==0 ! \n"; + assert(0); + return NULL; + } else { + // find out the maximum spread + // std::cout << "calc_spread()...\n"; + bool first = true; + BOOST_FOREACH (BBObj t, *tris) { // check each triangle + for (unsigned int m = 0; m < dimensions.size(); ++m) { + // dimensions[m] is the dimensions we want to update + // t.bb[ dimensions[m] ] is the update value + if (first) { + maxval[dimensions[m]] = t.bb[dimensions[m]]; + minval[dimensions[m]] = t.bb[dimensions[m]]; + if (m == (dimensions.size() - 1)) + first = false; + } else { + if (maxval[dimensions[m]] < t.bb[dimensions[m]]) + maxval[dimensions[m]] = t.bb[dimensions[m]]; + if (minval[dimensions[m]] > t.bb[dimensions[m]]) + minval[dimensions[m]] = t.bb[dimensions[m]]; + } + } } - Spread* spr = calc_spread(tris); // calculate spread in order to know how to cut - double cutvalue = spr->start + spr->val/2; // cut in the middle - //std::cout << " cutvalue= " << cutvalue << "\n"; - if ( (tris->size() <= bucketSize) || isZero_tol( spr->val ) ) { // then return a bucket/leaf node - //std::cout << "KDNode::build_node BUCKET list.size()=" << tris->size() << "\n"; - KDNode *bucket; // dim cutv parent hi lo triangles depth - bucket = new KDNode(spr->d, cutvalue , par , NULL, NULL, tris, dep); - assert( bucket->isLeaf ); - delete spr; - return bucket; // this is the leaf/end of the recursion-tree + std::vector spreads; // calculate the spread along each dimension + for (unsigned int m = 0; m < dimensions.size(); ++m) { // dim, spread, start + spreads.push_back( + new Spread(dimensions[m], maxval[dimensions[m]] - minval[dimensions[m]], minval[dimensions[m]])); + } // priority-queue could also be used ?? + assert(!spreads.empty()); + // std::cout << " spreads.size()=" << spreads.size() << "\n"; + std::sort(spreads.begin(), spreads.end(), Spread::spread_compare); // sort the list + Spread *s = new Spread(*spreads[0]); // this is the one we want to return + while (!spreads.empty()) + delete spreads.back(), spreads.pop_back(); // delete the others + // std::cout << "calc_spread() done\n"; + return s; // select the biggest spread and return + } // end tris->size != 0 + } // end spread(); + + /// search kd-tree starting at *node, looking for overlap with bb, and placing + /// found objects in *tris + void search_node(std::list *tris, const Bbox &bb, KDNode *node) { + if (node->isLeaf) { // we found a bucket node, so add all triangles and return. + + BOOST_FOREACH (BBObj t, *(node->tris)) { + tris->push_back(t); } - // build lists of triangles for hi and lo child nodes - std::list* lolist = new std::list(); - std::list* hilist = new std::list(); - BOOST_FOREACH(BBObj t, *tris) { // loop through each triangle and put it in either lolist or hilist - if (t.bb[spr->d] > cutvalue) - hilist->push_back(t); - else - lolist->push_back(t); - } - - /* - if (hilist->empty() || lolist->empty()) {// an error ?? - std::cout << "kdtree: hilist.size()==0! or lolist.size()==0! \n"; - std::cout << "kdtree: tris->size()= " << tris->size()<< "\n"; - std::cout << "kdtree: hilist.size()= " << hilist->size()<< "\n"; - std::cout << "kdtree: lolist.size()= " << lolist->size()<< "\n"; - BOOST_FOREACH(BBObj t, *tris) { - std::cout << t << "\n"; - std::cout << t.bb << "\n"; - } - std::cout << "kdtree: spr->d= " << spr->d << "\n"; - std::cout << "kdtree: cutvalue= " << cutvalue << "\n"; - assert(0); - }*/ - - - // create the current node dim value parent hi lo trilist depth - KDNode *node = new KDNode(spr->d, cutvalue, par, NULL,NULL,NULL, dep); - // create the child-nodes through recursion - // list depth parent - if (!hilist->empty()) - node->hi = build_node(hilist, dep+1, node); - //else - //std::cout << "hilist empty!\n"; - - if (!lolist->empty()) { - node->lo = build_node(lolist, dep+1, node); - } else { - //std::cout << "lolist empty!\n"; + // std::cout << " search_node Leaf bucket tris-size() = " << tris->size() << "\n"; + return; // end recursion + } else if ((node->dim % 2) == 0) { // cutting along a min-direction: 0, 2, 4 + // not a bucket node, so recursevily search hi/lo branches of KDNode + unsigned int maxdim = node->dim + 1; + if (node->cutval > bb[maxdim]) { // search only lo + search_node(tris, bb, node->lo); + } else { // need to search both child nodes + if (node->hi) + search_node(tris, bb, node->hi); + if (node->lo) + search_node(tris, bb, node->lo); } - - lolist->clear(); - hilist->clear(); - delete spr; - delete lolist; - delete hilist; - - return node; // return a new node - }; - - /// calculate the spread of list *tris - Spread* calc_spread(const std::list *tris) { - std::vector maxval( 6 ); - std::vector minval( 6 ); - if ( tris->empty() ) { - std::cout << " ERROR, KDTree::calc_spread() called with tris->size()==0 ! \n"; - assert( 0 ); - return NULL; - } else { - // find out the maximum spread - //std::cout << "calc_spread()...\n"; - bool first=true; - BOOST_FOREACH(BBObj t, *tris) { // check each triangle - for (unsigned int m=0;m t.bb[ dimensions[m] ]) - minval[ dimensions[m] ] = t.bb[ dimensions[m] ]; - } - } - } - std::vector spreads;// calculate the spread along each dimension - for (unsigned int m=0;msize != 0 - } // end spread(); - - - /// search kd-tree starting at *node, looking for overlap with bb, and placing - /// found objects in *tris - void search_node( std::list *tris, const Bbox& bb, KDNode *node) { - if (node->isLeaf ) { // we found a bucket node, so add all triangles and return. - - BOOST_FOREACH( BBObj t, *(node->tris) ) { - tris->push_back(t); - } - //std::cout << " search_node Leaf bucket tris-size() = " << tris->size() << "\n"; - return; // end recursion - } else if ( (node->dim % 2) == 0) { // cutting along a min-direction: 0, 2, 4 - // not a bucket node, so recursevily search hi/lo branches of KDNode - unsigned int maxdim = node->dim+1; - if ( node->cutval > bb[maxdim] ) { // search only lo - search_node(tris, bb, node->lo ); - } else { // need to search both child nodes - if (node->hi) - search_node(tris, bb, node->hi ); - if (node->lo) - search_node(tris, bb, node->lo ); - } - } else { // cutting along a max-dimension: 1,3,5 - unsigned int mindim = node->dim-1; - if ( node->cutval < bb[mindim] ) { // search only hi + } else { // cutting along a max-dimension: 1,3,5 + unsigned int mindim = node->dim - 1; + if (node->cutval < bb[mindim]) { // search only hi + search_node(tris, bb, node->hi); + } else { // need to search both child nodes + if (node->hi) search_node(tris, bb, node->hi); - } else { // need to search both child nodes - if (node->hi) - search_node(tris, bb, node->hi); - if (node->lo) - search_node(tris, bb, node->lo); - } + if (node->lo) + search_node(tris, bb, node->lo); } - return; // Done. We get here after all the recursive calls above. - } // end search_kdtree(); - // DATA - /// bucket size of tree - unsigned int bucketSize; - /// pointer to root KDNode - KDNode* root; - /// the dimensions in this kd-tree - std::vector dimensions; + } + return; // Done. We get here after all the recursive calls above. + } // end search_kdtree(); + // DATA + /// bucket size of tree + unsigned int bucketSize; + /// pointer to root KDNode + KDNode *root; + /// the dimensions in this kd-tree + std::vector dimensions; }; -} // end ocl namespace +} // namespace ocl #endif // end file kdtree.hpp diff --git a/src/common/lineclfilter.cpp b/src/common/lineclfilter.cpp index 3c148c0a..b398355d 100644 --- a/src/common/lineclfilter.cpp +++ b/src/common/lineclfilter.cpp @@ -1,50 +1,43 @@ /* $Id$ - * + * * Copyright (c) 2010-2011 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #include "lineclfilter.hpp" -#include "point.hpp" #include "clpoint.hpp" +#include "point.hpp" -namespace ocl -{ +namespace ocl { -LineCLFilter::LineCLFilter() { - clpoints.clear(); -} +LineCLFilter::LineCLFilter() { clpoints.clear(); } -void LineCLFilter::addCLPoint(const CLPoint& p) { - clpoints.push_back(p); -} -void LineCLFilter::setTolerance(const double tolerance) { - tol = tolerance; -} +void LineCLFilter::addCLPoint(const CLPoint &p) { clpoints.push_back(p); } +void LineCLFilter::setTolerance(const double tolerance) { tol = tolerance; } void LineCLFilter::run() { typedef std::list::iterator cl_itr; size_t n = clpoints.size(); - if (n<2) + if (n < 2) return; // can't filter lists of length 0, 1, or 2 std::list new_list; - + cl_itr p0 = clpoints.begin(); cl_itr p1 = clpoints.begin(); p1++; @@ -56,14 +49,15 @@ void LineCLFilter::run() { bool even_number = true; - for( ; p2 != clpoints.end(); ) { + for (; p2 != clpoints.end();) { Point p = p1->closestPoint(*p0, *p2); - if((p - *p1).norm() < tol) { + if ((p - *p1).norm() < tol) { p_last_good = p2; p2++; - if(even_number)p1++; + if (even_number) + p1++; even_number = !even_number; - }else { + } else { new_list.push_back(*p_last_good); p0 = p_last_good; p1 = p2; @@ -76,5 +70,5 @@ void LineCLFilter::run() { return; } -} // end namespace +} // namespace ocl // end file lineclfilter.cpp diff --git a/src/common/lineclfilter.hpp b/src/common/lineclfilter.hpp index dd3a45b1..8118a381 100644 --- a/src/common/lineclfilter.hpp +++ b/src/common/lineclfilter.hpp @@ -1,49 +1,46 @@ /* $Id$ - * + * * Copyright (c) 2010-2011 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef LINE_CL_FILTER_H #define LINE_CL_FILTER_H #include "clfilter.hpp" -namespace ocl -{ +namespace ocl { /// LineCLFilter takes a sequence of cutter-location (CL) points /// as input and produces another sequence as output. /// -/// The number of CL-points is reduced by finding co-linear points, +/// The number of CL-points is reduced by finding co-linear points, /// to within a set tolerance, and deleting redundant ones. /// -class LineCLFilter : public CLFilter { - public: - LineCLFilter(); - ~LineCLFilter(){}; - void addCLPoint(const CLPoint& p); - void setTolerance(const double tol); - void run(); +class LineCLFilter : public CLFilter { + public: + LineCLFilter(); + ~LineCLFilter(){}; + void addCLPoint(const CLPoint &p); + void setTolerance(const double tol); + void run(); }; - - -} // end namespace +} // namespace ocl #endif // end file lineclfilter.h diff --git a/src/common/numeric.cpp b/src/common/numeric.cpp index 004c3719..b69d65b1 100644 --- a/src/common/numeric.cpp +++ b/src/common/numeric.cpp @@ -1,26 +1,26 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ -#include -#include // for fabs() + */ #include +#include // for fabs() +#include #include "numeric.hpp" #include "point.hpp" @@ -36,44 +36,44 @@ namespace ocl { double xyVectorToDiangle(double x, double y) { double diangle; if (y >= 0) - diangle = (x >= 0 ? y/(x+y) : 1-x/(-x+y)); + diangle = (x >= 0 ? y / (x + y) : 1 - x / (-x + y)); else - diangle = (x < 0 ? 2-y/(-x-y) : 3+x/(x-y)); + diangle = (x < 0 ? 2 - y / (-x - y) : 3 + x / (x - y)); #ifdef _WIN32 - if ((boost::math::isnan)(diangle)) { // Use the Boost version + if ((boost::math::isnan)(diangle)) { // Use the Boost version #else - if (std::isnan(diangle) ) { // Use the std version + if (std::isnan(diangle)) { // Use the std version #endif - std::cout << "numeric::xyVectorToDiangle() error (x,y)= ("<< x << " , " << y << " ) and diangle=" << diangle << "\n"; + std::cout << "numeric::xyVectorToDiangle() error (x,y)= (" << x << " , " << y << " ) and diangle=" << diangle + << "\n"; assert(0); } return diangle; } - double sign(double x) { - if (x<0.0) + if (x < 0.0) return -1; else return 1; } bool isPositive(double x) { - if (x > 0.0 ) + if (x > 0.0) return true; else return false; } bool isNegative(double x) { - if ( x < 0.0 ) + if (x < 0.0) return true; else return false; } bool isZero_tol(double x) { - if (fabs(x) // [ (p2-p1).x -(p4-p3).x ] [ v ] = [ (p3-p1).x ] // [ (p2-p1).y -(p4-p3).y ] [ t ] = [ (p3-p1).y ] - return two_by_two_solver( (p2-p1).x , -(p4-p3).x , (p2-p1).y , -(p4-p3).y, (p3-p1).x, (p3-p1).y, v, t); + return two_by_two_solver((p2 - p1).x, -(p4 - p3).x, (p2 - p1).y, -(p4 - p3).y, (p3 - p1).x, (p3 - p1).y, v, t); } - -} // end namespace +} // namespace ocl // end file numeric.cpp diff --git a/src/common/numeric.hpp b/src/common/numeric.hpp index b2ccae2b..a69f94ef 100644 --- a/src/common/numeric.hpp +++ b/src/common/numeric.hpp @@ -1,23 +1,23 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef NUMERIC_H #define NUMERIC_H @@ -33,9 +33,8 @@ // #endif #include // isnan -namespace ocl -{ - +namespace ocl { + #define PI 3.1415926535897932 /// @@ -47,9 +46,7 @@ namespace ocl double sign(double x); /// return x*x -inline double square(double x) { - return x*x; -} +inline double square(double x) { return x * x; } /// return true if x is negative bool isNegative(double x); @@ -57,43 +54,36 @@ bool isNegative(double x); /// return true if x is negative bool isPositive(double x); -/// return true if x is zero, to within tolerance +/// return true if x is zero, to within tolerance bool isZero_tol(double x); /// returns machine-epsilon /// eps is such that 1 < 1 + eps -/// but 1 == 1 + eps/2 +/// but 1 == 1 + eps/2 double eps(); double epsD(double x); float epsF(float x); /// assertion with error message -void assert_msg( bool assertion, std::string message); +void assert_msg(bool assertion, std::string message); /// solves 2x2 matrix system Ax=y, solution is x = Ainv * y /// [ a b ] [u] = [ e ] /// [ c d ] [v] = [ f ] - -bool two_by_two_solver( const double& a, - const double& b, - const double& c, - const double& d, - const double& e, - const double& f, - double& u, - double& v); + +bool two_by_two_solver(const double &a, const double &b, const double &c, const double &d, const double &e, + const double &f, double &u, double &v); /// returns intersection in XY plane btw. lines p1,p2 and p3,p4 /// line1 is p1 + v * (p2-p1) /// line2 is p3 + t * (p4-p3) -bool xy_line_line_intersection( const Point& p1, const Point& p2, double& v, - const Point& p3, const Point& p4, double& t); +bool xy_line_line_intersection(const Point &p1, const Point &p2, double &v, const Point &p3, const Point &p4, + double &t); /// convert the direction (x,y) into a diangle double xyVectorToDiangle(double x, double y); - -} // end ocl namespace +} // namespace ocl #endif // end file numeric.hpp diff --git a/src/cutters/ballcutter.cpp b/src/cutters/ballcutter.cpp index 6316e1a5..c60dba59 100644 --- a/src/cutters/ballcutter.cpp +++ b/src/cutters/ballcutter.cpp @@ -1,23 +1,23 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #include #include @@ -27,8 +27,7 @@ #include "ballcutter.hpp" -namespace ocl -{ +namespace ocl { BallCutter::BallCutter() { std::cout << " usage: BallCutter( double diameter, double length )\n"; @@ -36,9 +35,11 @@ BallCutter::BallCutter() { } BallCutter::BallCutter(double d, double l) { - diameter = d; assert( diameter>0.0 ); - radius = d/2.0; - length = l; assert( length>0.0 ); + diameter = d; + assert(diameter > 0.0); + radius = d / 2.0; + length = l; + assert(length > 0.0); normal_length = radius; xy_normal_length = 0.0; center_height = radius; @@ -46,36 +47,36 @@ BallCutter::BallCutter(double d, double l) { // drop-cutter methods: vertex and facet are handled in base-class -// drop-cutter edgeDrop -CC_CLZ_Pair BallCutter::singleEdgeDropCanonical(const Point& u1, const Point& u2) const { +// drop-cutter edgeDrop +CC_CLZ_Pair BallCutter::singleEdgeDropCanonical(const Point &u1, const Point &u2) const { // the plane of the line will slice the spherical cutter at // a distance d==u1.y==u2.y from the center of the cutter // here the radius of the circular section is s: - double s = sqrt( square(radius) - square( u1.y ) ); - Point normal(u2.z - u1.z, -(u2.x - u1.x), 0); // (dz, -du) is a normal to the line + double s = sqrt(square(radius) - square(u1.y)); + Point normal(u2.z - u1.z, -(u2.x - u1.x), 0); // (dz, -du) is a normal to the line normal.xyNormalize(); - if (normal.y < 0) // flip normal so it points upward - normal = -1*normal; - Point cc( -s*normal.x, u1.y, 0); // from (0,u1.y,0) we go a distance -s in the normal direction - cc.z_projectOntoEdge(u1,u2); - double cl_z = cc.z + s*normal.y - radius; - return CC_CLZ_Pair( cc.x , cl_z); + if (normal.y < 0) // flip normal so it points upward + normal = -1 * normal; + Point cc(-s * normal.x, u1.y, 0); // from (0,u1.y,0) we go a distance -s in the normal direction + cc.z_projectOntoEdge(u1, u2); + double cl_z = cc.z + s * normal.y - radius; + return CC_CLZ_Pair(cc.x, cl_z); } // push-cutter: vertex and facet handled in base-class -bool BallCutter::generalEdgePush(const Fiber& f, Interval& i, const Point& p1, const Point& p2) const { +bool BallCutter::generalEdgePush(const Fiber &f, Interval &i, const Point &p1, const Point &p2) const { bool result = false; - if ( isZero_tol( (p2-p1).xyNorm() ) ) { // this would be a vertical edge + if (isZero_tol((p2 - p1).xyNorm())) { // this would be a vertical edge return result; } - - const Point ufp1 = f.p1 + Point(0,0,radius); // take a fiber which is raised up by radius - const Point ufp2 = f.p2 + Point(0,0,radius); // and intersect it with a cylinder around the edge p1-p2 + + const Point ufp1 = f.p1 + Point(0, 0, radius); // take a fiber which is raised up by radius + const Point ufp2 = f.p2 + Point(0, 0, radius); // and intersect it with a cylinder around the edge p1-p2 // Ray : P(t) = O + t*V from point O, in direction V // Cylinder [A, B, r] from point A to point B, radius r // Point P on infinite cylinder if ((P - A) x (B - A))^2 = r^2 * (B - A)^2 // expand : ((O - A) x (B - A) + t * (V x (B - A)))^2 = r^2 * (B - A)^2 - // equation in the form (X + t * Y)^2 = d , where: + // equation in the form (X + t * Y)^2 = d , where: // X = (O - A) x (B - A) // Y = V x (B - A) // d = r^2 * (B - A)^2 @@ -85,54 +86,55 @@ bool BallCutter::generalEdgePush(const Fiber& f, Interval& i, const Point& p1, // a = (Y . Y) // b = 2 * (X . Y) // c = (X . X) - d - Point ab = p2-p1; // axis of the cylinder - Point ao = (ufp1 - p1); // cyl start to ray start - Point ao_x_ab = ao.cross(ab); // cross product - Point v_x_ab = (ufp2-ufp1).cross(ab); // cross product - double ab2 = ab.dot(ab); // dot product - double a = v_x_ab.dot(v_x_ab); // dot product - double b = 2 * ( v_x_ab.dot(ao_x_ab) ); // dot product - double c = ao_x_ab.dot(ao_x_ab) - (radius*radius * ab2); + Point ab = p2 - p1; // axis of the cylinder + Point ao = (ufp1 - p1); // cyl start to ray start + Point ao_x_ab = ao.cross(ab); // cross product + Point v_x_ab = (ufp2 - ufp1).cross(ab); // cross product + double ab2 = ab.dot(ab); // dot product + double a = v_x_ab.dot(v_x_ab); // dot product + double b = 2 * (v_x_ab.dot(ao_x_ab)); // dot product + double c = ao_x_ab.dot(ao_x_ab) - (radius * radius * ab2); // solve second order equation : a*t^2 + b*t + c = 0 // t = (-b +/- sqrt( b^2 - 4ac ) ) / 2a - double discr = b*b-4*a*c; + double discr = b * b - 4 * a * c; double t1, t2; - if ( isZero_tol( discr ) ) { // tangent case, only one root - t1= -b/(2*a); - if ( calcCCandUpdateInterval( t1, p1, p2, f, i ) ) + if (isZero_tol(discr)) { // tangent case, only one root + t1 = -b / (2 * a); + if (calcCCandUpdateInterval(t1, p1, p2, f, i)) result = true; - } else if ( discr > 0.0 ) { // two roots - t1 = (-b + sqrt( discr))/(2*a); - t2 = (-b - sqrt( discr))/(2*a); - if ( calcCCandUpdateInterval( t1, p1, p2, f, i ) ) + } else if (discr > 0.0) { // two roots + t1 = (-b + sqrt(discr)) / (2 * a); + t2 = (-b - sqrt(discr)) / (2 * a); + if (calcCCandUpdateInterval(t1, p1, p2, f, i)) result = true; - if ( calcCCandUpdateInterval( t2, p1, p2, f, i ) ) + if (calcCCandUpdateInterval(t2, p1, p2, f, i)) result = true; - } + } return result; } // t is a position along the fiber // p1-p2 is the edge // Interval& i is updated -bool BallCutter::calcCCandUpdateInterval( double t, const Point& p1, const Point& p2, const Fiber& f, Interval& i) const { - Point cl_center = f.point(t) + Point(0,0,radius); // center of ball is here - CCPoint cc_tmp = cl_center.closestPoint(p1,p2); // cc-point on the edge, point on edge closest to center +bool BallCutter::calcCCandUpdateInterval(double t, const Point &p1, const Point &p2, const Fiber &f, + Interval &i) const { + Point cl_center = f.point(t) + Point(0, 0, radius); // center of ball is here + CCPoint cc_tmp = cl_center.closestPoint(p1, p2); // cc-point on the edge, point on edge closest to center cc_tmp.type = EDGE_BALL; // require contact with lower hemishphere - return i.update_ifCCinEdgeAndTrue( t, cc_tmp, p1, p2, ((cl_center-cc_tmp).z >=0) ); + return i.update_ifCCinEdgeAndTrue(t, cc_tmp, p1, p2, ((cl_center - cc_tmp).z >= 0)); } - + std::string BallCutter::str() const { std::ostringstream o; - o << *this; + o << *this; return o.str(); } -std::ostream& operator<<(std::ostream &stream, BallCutter c) { - stream << "BallCutter(d=" << c.diameter << ", r=" << c.radius << ", L=" << c.length << ")"; - return stream; +std::ostream &operator<<(std::ostream &stream, BallCutter c) { + stream << "BallCutter(d=" << c.diameter << ", r=" << c.radius << ", L=" << c.length << ")"; + return stream; } -} // end namespace +} // namespace ocl // end file ballcutter.cpp diff --git a/src/cutters/ballcutter.hpp b/src/cutters/ballcutter.hpp index 6198bba9..ea71854f 100644 --- a/src/cutters/ballcutter.hpp +++ b/src/cutters/ballcutter.hpp @@ -1,23 +1,23 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef BALL_CUTTER_H #define BALL_CUTTER_H @@ -28,30 +28,30 @@ #include "millingcutter.hpp" #include "numeric.hpp" -namespace ocl -{ +namespace ocl { /// \brief Ball or Spherical MillingCutter (ball-nose endmill) /// class BallCutter : public MillingCutter { - public: - BallCutter(); - /// create a BallCutter with diameter d (radius d/2) and length l - explicit BallCutter(double d, double l); - /// offset of Ball is Ball - MillingCutter* offsetCutter(double d) const {return new BallCutter(diameter+2*d, length+d);} - /// string repr - friend std::ostream& operator<<(std::ostream &stream, BallCutter c); - std::string str() const; - protected: - CC_CLZ_Pair singleEdgeDropCanonical(const Point& u1, const Point& u2) const; - bool generalEdgePush(const Fiber& f, Interval& i, const Point& p1, const Point& p2) const; - /// calculate CC-point and update Interval i - bool calcCCandUpdateInterval( double t, const Point& p1, const Point& p2, const Fiber& f, Interval& i) const; - double height(double r) const {return radius - sqrt( square(radius) - square(r) );} - double width(double h) const {return ( h >= radius ) ? radius : sqrt( square(radius) - square(radius-h) ); } + public: + BallCutter(); + /// create a BallCutter with diameter d (radius d/2) and length l + explicit BallCutter(double d, double l); + /// offset of Ball is Ball + MillingCutter *offsetCutter(double d) const { return new BallCutter(diameter + 2 * d, length + d); } + /// string repr + friend std::ostream &operator<<(std::ostream &stream, BallCutter c); + std::string str() const; + + protected: + CC_CLZ_Pair singleEdgeDropCanonical(const Point &u1, const Point &u2) const; + bool generalEdgePush(const Fiber &f, Interval &i, const Point &p1, const Point &p2) const; + /// calculate CC-point and update Interval i + bool calcCCandUpdateInterval(double t, const Point &p1, const Point &p2, const Fiber &f, Interval &i) const; + double height(double r) const { return radius - sqrt(square(radius) - square(r)); } + double width(double h) const { return (h >= radius) ? radius : sqrt(square(radius) - square(radius - h)); } }; -} // end namespace +} // namespace ocl #endif // end ballcutter.h diff --git a/src/cutters/bullcutter.cpp b/src/cutters/bullcutter.cpp index 1412c43a..6ec3943f 100644 --- a/src/cutters/bullcutter.cpp +++ b/src/cutters/bullcutter.cpp @@ -1,23 +1,23 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #include #include #include @@ -27,8 +27,7 @@ #include "bullcutter.hpp" #include "numeric.hpp" -namespace ocl -{ +namespace ocl { BullCutter::BullCutter() { std::cout << " usage: BullCutter( double diameter, double corner_radius, double length ) \n"; @@ -36,26 +35,29 @@ BullCutter::BullCutter() { } BullCutter::BullCutter(double d, double r, double l) { - diameter = d; assert( d > 0.0 ); - radius = d/2.0; // total cutter radius - radius1 = d/2.0 - r; // cylindrical middle part radius - radius2 = r; assert( radius1 > 0.0 ); // corner radius - length = l; assert( l > 0.0 ); + diameter = d; + assert(d > 0.0); + radius = d / 2.0; // total cutter radius + radius1 = d / 2.0 - r; // cylindrical middle part radius + radius2 = r; + assert(radius1 > 0.0); // corner radius + length = l; + assert(l > 0.0); xy_normal_length = radius1; normal_length = radius2; center_height = radius2; } -MillingCutter* BullCutter::offsetCutter(double d) const { - return new BullCutter(diameter+2*d, radius2+d, length+d) ; +MillingCutter *BullCutter::offsetCutter(double d) const { + return new BullCutter(diameter + 2 * d, radius2 + d, length + d); } // height of cutter at radius r double BullCutter::height(double r) const { - if ( r <= radius1 ) + if (r <= radius1) return 0.0; // cylinder - else if ( r <= radius ) - return radius2 - sqrt( square(radius2) - square(r-radius1) ); // toroid + else if (r <= radius) + return radius2 - sqrt(square(radius2) - square(r - radius1)); // toroid else { assert(0); return -1; @@ -64,7 +66,7 @@ double BullCutter::height(double r) const { // width of cutter at height h double BullCutter::width(double h) const { - return ( h >= radius2 ) ? radius : radius1 + sqrt(square(radius2)-square(radius2-h)) ; + return (h >= radius2) ? radius : radius1 + sqrt(square(radius2) - square(radius2 - h)); } // drop-cutter: vertex and facet are handled in base-class @@ -79,78 +81,78 @@ double BullCutter::width(double h) const { // when a radius2 cylinder around the edge is sliced by an XY plane this // results in an ellipse with a shorter axis of radius2, and a longer axis of radius2/sin(theta) // where theta is the slope of the edge in the XZ plane -CC_CLZ_Pair BullCutter::singleEdgeDropCanonical( const Point& u1, const Point& u2 ) const { - if ( isZero_tol( u1.z - u2.z ) ) { // horizontal edge special case - return CC_CLZ_Pair( 0 , u1.z - height(u1.y) ); - } else { // the general offset-ellipse case +CC_CLZ_Pair BullCutter::singleEdgeDropCanonical(const Point &u1, const Point &u2) const { + if (isZero_tol(u1.z - u2.z)) { // horizontal edge special case + return CC_CLZ_Pair(0, u1.z - height(u1.y)); + } else { // the general offset-ellipse case double b_axis = radius2; // short axis of ellipse = radius2 - double theta = atan( (u2.z - u1.z) / (u2.x-u1.x) ); // theta is the slope of the line - double a_axis = fabs( radius2/sin(theta) ); // long axis of ellipse = radius2/sin(theta) - Point ellcenter(0,u1.y,0); - Ellipse e = Ellipse( ellcenter, a_axis, b_axis, radius1); // radius1 is the ellipse-offset + double theta = atan((u2.z - u1.z) / (u2.x - u1.x)); // theta is the slope of the line + double a_axis = fabs(radius2 / sin(theta)); // long axis of ellipse = radius2/sin(theta) + Point ellcenter(0, u1.y, 0); + Ellipse e = Ellipse(ellcenter, a_axis, b_axis, radius1); // radius1 is the ellipse-offset int iters = e.solver_brent(); // numerical solver that searches for a point on the ellipse // such that a radius1-length normal-vector from this ellipse-point // is at the CL point (0,0) if (iters > 200) std::cout << "WARNING: BullCutter::singleEdgeDropCanonical() iters>200 !!\n"; - assert( iters < 200 ); - e.setEllipsePositionHi(u1,u2); // this selects either EllipsePosition1 or - // EllipsePosition2 and sets it to EllipsePosition_hi + assert(iters < 200); + e.setEllipsePositionHi(u1, u2); // this selects either EllipsePosition1 or + // EllipsePosition2 and sets it to EllipsePosition_hi // pseudo cc-point on the ellipse/cylinder, in the CL=(0,0) system Point ell_ccp = e.ePointHi(); - assert( fabs( ell_ccp.xyNorm() - radius1 ) < 1E-5); // ell_ccp should be on the cylinder-circle - Point cc_tmp_u = ell_ccp.closestPoint(u1,u2); // find cc-point on u1-u2 edge - return CC_CLZ_Pair( cc_tmp_u.x , e.getCenterZ()-radius2); + assert(fabs(ell_ccp.xyNorm() - radius1) < 1E-5); // ell_ccp should be on the cylinder-circle + Point cc_tmp_u = ell_ccp.closestPoint(u1, u2); // find cc-point on u1-u2 edge + return CC_CLZ_Pair(cc_tmp_u.x, e.getCenterZ() - radius2); } } // push-cutter: vertex and facet handled by base-class // edge handled here -bool BullCutter::generalEdgePush(const Fiber& f, Interval& i, const Point& p1, const Point& p2) const { - //std::cout << " BullCutter::generalEdgePush() \n"; +bool BullCutter::generalEdgePush(const Fiber &f, Interval &i, const Point &p1, const Point &p2) const { + // std::cout << " BullCutter::generalEdgePush() \n"; bool result = false; - - if ( isZero_tol( (p2-p1).xyNorm() ) ) { // this would be a vertical edge + + if (isZero_tol((p2 - p1).xyNorm())) { // this would be a vertical edge return result; } - - if ( isZero_tol( p2.z-p1.z ) ) // this would be a horizontal edge + + if (isZero_tol(p2.z - p1.z)) // this would be a horizontal edge return result; - assert( fabs(p2.z-p1.z) > 0.0 ); // no horiz edges allowed hereafter - - // p1+t*(p2-p1) = f.p1.z+radius2 => - double tplane = (f.p1.z + radius2 - p1.z ) / (p2.z-p1.z); // intersect edge with plane at z = ufp1.z - Point ell_center = p1+tplane*(p2-p1); - assert( isZero_tol( fabs(ell_center.z - (f.p1.z+radius2)) ) ); - Point major_dir = (p2-p1); - assert( major_dir.xyNorm() > 0.0 ); - + assert(fabs(p2.z - p1.z) > 0.0); // no horiz edges allowed hereafter + + // p1+t*(p2-p1) = f.p1.z+radius2 => + double tplane = (f.p1.z + radius2 - p1.z) / (p2.z - p1.z); // intersect edge with plane at z = ufp1.z + Point ell_center = p1 + tplane * (p2 - p1); + assert(isZero_tol(fabs(ell_center.z - (f.p1.z + radius2)))); + Point major_dir = (p2 - p1); + assert(major_dir.xyNorm() > 0.0); + major_dir.z = 0; major_dir.xyNormalize(); Point minor_dir = major_dir.xyPerp(); - double theta = atan( (p2.z - p1.z) / (p2-p1).xyNorm() ); - double major_length = fabs( radius2/sin(theta) ) ; + double theta = atan((p2.z - p1.z) / (p2 - p1).xyNorm()); + double major_length = fabs(radius2 / sin(theta)); double minor_length = radius2; - AlignedEllipse e(ell_center, major_length, minor_length, radius1, major_dir, minor_dir ); - if ( e.aligned_solver( f ) ) { // now we want the offset-ellipse point to lie on the fiber - Point pseudo_cc = e.ePoint1(); // pseudo cc-point on ellipse and cylinder + AlignedEllipse e(ell_center, major_length, minor_length, radius1, major_dir, minor_dir); + if (e.aligned_solver(f)) { // now we want the offset-ellipse point to lie on the fiber + Point pseudo_cc = e.ePoint1(); // pseudo cc-point on ellipse and cylinder Point pseudo_cc2 = e.ePoint2(); - CCPoint cc = pseudo_cc.closestPoint(p1,p2); - CCPoint cc2 = pseudo_cc2.closestPoint(p1,p2); - cc.type = EDGE_POS; + CCPoint cc = pseudo_cc.closestPoint(p1, p2); + CCPoint cc2 = pseudo_cc2.closestPoint(p1, p2); + cc.type = EDGE_POS; cc2.type = EDGE_POS; - Point cl = e.oePoint1() - Point(0,0,center_height); - assert( isZero_tol( fabs(cl.z - f.p1.z)) ); - Point cl2 = e.oePoint2() - Point(0,0,center_height); - assert( isZero_tol( fabs(cl2.z - f.p1.z)) ); - double cl_t = f.tval(cl); + Point cl = e.oePoint1() - Point(0, 0, center_height); + assert(isZero_tol(fabs(cl.z - f.p1.z))); + Point cl2 = e.oePoint2() - Point(0, 0, center_height); + assert(isZero_tol(fabs(cl2.z - f.p1.z))); + double cl_t = f.tval(cl); double cl_t2 = f.tval(cl2); - if ( i.update_ifCCinEdgeAndTrue( cl_t, cc, p1, p2, true ) ) + if (i.update_ifCCinEdgeAndTrue(cl_t, cc, p1, p2, true)) result = true; - if ( i.update_ifCCinEdgeAndTrue( cl_t2, cc2, p1, p2, true ) ) + if (i.update_ifCCinEdgeAndTrue(cl_t2, cc2, p1, p2, true)) result = true; } - //std::cout << " BullCutter::generalEdgePush() DONE result= " << result << "\n"; + // std::cout << " BullCutter::generalEdgePush() DONE result= " << result << "\n"; return result; } @@ -160,10 +162,10 @@ std::string BullCutter::str() const { return o.str(); } -std::ostream& operator<<(std::ostream &stream, BullCutter c) { - stream << "BullCutter(d=" << c.diameter << ", r1=" << c.radius1 << " r2=" << c.radius2 << ", L=" << c.length << ")"; - return stream; +std::ostream &operator<<(std::ostream &stream, BullCutter c) { + stream << "BullCutter(d=" << c.diameter << ", r1=" << c.radius1 << " r2=" << c.radius2 << ", L=" << c.length << ")"; + return stream; } -} // end namespace +} // namespace ocl // end file bullcutter.cpp diff --git a/src/cutters/bullcutter.hpp b/src/cutters/bullcutter.hpp index a2ca0861..118a4814 100644 --- a/src/cutters/bullcutter.hpp +++ b/src/cutters/bullcutter.hpp @@ -1,23 +1,23 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef BULL_CUTTER_H #define BULL_CUTTER_H @@ -26,38 +26,36 @@ #include #include -#include "millingcutter.hpp" #include "ellipse.hpp" +#include "millingcutter.hpp" -namespace ocl -{ +namespace ocl { /// \brief Bull-nose or Toroidal MillingCutter (filleted endmill) /// /// defined by the cutter diameter and by the corner radius /// class BullCutter : public MillingCutter { - public: - BullCutter(); - /// Create bull-cutter with diamter d, corner radius r, and length l. - BullCutter(double diameter, double radius, double length); - /// offset of Bull is Bull - MillingCutter* offsetCutter(double offset) const; - /// string repr - friend std::ostream& operator<<(std::ostream &stream, BullCutter c); - std::string str() const; - - protected: - - bool generalEdgePush(const Fiber& f, Interval& i, const Point& p1, const Point& p2) const; - CC_CLZ_Pair singleEdgeDropCanonical(const Point& u1, const Point& u2) const; - double height(double r) const; - double width(double h) const; - /// radius of cylindrical part of cutter - double radius1; - /// tube radius of torus - double radius2; + public: + BullCutter(); + /// Create bull-cutter with diamter d, corner radius r, and length l. + BullCutter(double diameter, double radius, double length); + /// offset of Bull is Bull + MillingCutter *offsetCutter(double offset) const; + /// string repr + friend std::ostream &operator<<(std::ostream &stream, BullCutter c); + std::string str() const; + + protected: + bool generalEdgePush(const Fiber &f, Interval &i, const Point &p1, const Point &p2) const; + CC_CLZ_Pair singleEdgeDropCanonical(const Point &u1, const Point &u2) const; + double height(double r) const; + double width(double h) const; + /// radius of cylindrical part of cutter + double radius1; + /// tube radius of torus + double radius2; }; -} // end namespace +} // namespace ocl #endif diff --git a/src/cutters/compositecutter.cpp b/src/cutters/compositecutter.cpp index 84fe7cfd..4d9a6fc8 100644 --- a/src/cutters/compositecutter.cpp +++ b/src/cutters/compositecutter.cpp @@ -17,43 +17,40 @@ * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #include #include #include -#include "compositecutter.hpp" -#include "numeric.hpp" -#include "cylcutter.hpp" #include "ballcutter.hpp" #include "bullcutter.hpp" +#include "compositecutter.hpp" #include "conecutter.hpp" +#include "cylcutter.hpp" +#include "numeric.hpp" -namespace ocl -{ +namespace ocl { CompositeCutter::CompositeCutter() { radiusvec = std::vector(); - cutter = std::vector(); - radius=0; - diameter=0; + cutter = std::vector(); + radius = 0; + diameter = 0; } // add cutter c which is valid until radius=r and height=z with z-offset zoff -void CompositeCutter::addCutter(MillingCutter& c, double r, double h, double zoff) { +void CompositeCutter::addCutter(MillingCutter &c, double r, double h, double zoff) { radiusvec.push_back(r); heightvec.push_back(h); cutter.push_back(&c); zoffset.push_back(zoff); - if (r>radius) { + if (r > radius) { radius = r; - diameter = 2*r; + diameter = 2 * r; } // update length also? } - - // this allows vertexDrop in the base-class to work as for other cutters double CompositeCutter::height(double r) const { unsigned int idx = radius_to_index(r); @@ -65,12 +62,12 @@ double CompositeCutter::width(double h) const { unsigned int idx = height_to_index(h); // std::cout << "CompositeCutter::width( " << h << " ) idx=" << idx << " zoffset= " << zoffset[idx] << "\n"; // std::cout << " width = " << cutter[idx]->width( h - zoffset[idx] ) << "\n"; - return cutter[idx]->width( h - zoffset[idx] ); + return cutter[idx]->width(h - zoffset[idx]); } unsigned int CompositeCutter::height_to_index(double h) const { - for (unsigned int n=0; ntype == NONE) return false; double d = cl.xyDistance(*cl.cc); double lolimit; double hilimit; - if (n==0) - lolimit = - 1E-6; + if (n == 0) + lolimit = -1E-6; else - lolimit = radiusvec[n-1] - 1E-6; - hilimit = radiusvec[n]+1e-6; // FIXME: really ugly solution this one... - if (dhilimit) + else if (d > hilimit) return false; else return true; } -bool CompositeCutter::ccValidHeight(unsigned int n, CCPoint& cc, const Fiber& f) const { - //if ( ((cc.z-f.p1.z) >= 0.0) && (n == height_to_index(cc.z-f.p1.z)) ) - if ( n == height_to_index(cc.z-f.p1.z) ) +bool CompositeCutter::ccValidHeight(unsigned int n, CCPoint &cc, const Fiber &f) const { + // if ( ((cc.z-f.p1.z) >= 0.0) && (n == height_to_index(cc.z-f.p1.z)) ) + if (n == height_to_index(cc.z - f.p1.z)) return true; else return false; @@ -120,28 +116,27 @@ bool CompositeCutter::ccValidHeight(unsigned int n, CCPoint& cc, const Fiber& f) // return true if height h belongs to cutter n bool CompositeCutter::validHeight(unsigned int n, double h) const { double lolimit, hilimit; - if (n==0) + if (n == 0) lolimit = -1E-6; else - lolimit = heightvec[n-1] - 1E-6; - hilimit = heightvec[n]+1e-6; // FIXME: really ugly solution this one... - if ( (lolimit<=h) ) - if (h<=hilimit) + lolimit = heightvec[n - 1] - 1E-6; + hilimit = heightvec[n] + 1e-6; // FIXME: really ugly solution this one... + if ((lolimit <= h)) + if (h <= hilimit) return true; return false; } - bool CompositeCutter::validRadius(unsigned int n, double r) const { - assert( r >= 0.0 ); + assert(r >= 0.0); double lolimit, hilimit; - if (n==0) + if (n == 0) lolimit = -1E-6; else - lolimit = radiusvec[n-1] - 1E-6; - hilimit = radiusvec[n]+1e-6; // FIXME: really ugly solution this one... - if ( (lolimit<=r) ) - if (r<=hilimit) + lolimit = radiusvec[n - 1] - 1E-6; + hilimit = radiusvec[n] + 1e-6; // FIXME: really ugly solution this one... + if ((lolimit <= r)) + if (r <= hilimit) return true; return false; } @@ -151,14 +146,14 @@ bool CompositeCutter::validRadius(unsigned int n, double r) const { // call facetDrop on each cutter and pick a valid cc-point bool CompositeCutter::facetDrop(CLPoint &cl, const Triangle &t) const { bool result = false; - for (unsigned int n=0; nfacetDrop(cl_tmp, t) ) { - assert( cl_tmp.cc != 0); - if ( ccValidRadius(n,cl_tmp) ) { // cc-point is valid + for (unsigned int n = 0; n < cutter.size(); ++n) { // loop through cutters + CLPoint cl_tmp = cl + CLPoint(0, 0, zoffset[n]); + CCPoint *cc_tmp; + if (cutter[n]->facetDrop(cl_tmp, t)) { + assert(cl_tmp.cc != 0); + if (ccValidRadius(n, cl_tmp)) { // cc-point is valid cc_tmp = new CCPoint(*cl_tmp.cc); - if (cl.liftZ( cl_tmp.z - zoffset[n] )) { // we need to lift the cutter + if (cl.liftZ(cl_tmp.z - zoffset[n])) { // we need to lift the cutter cc_tmp->type = FACET; cl.cc = cc_tmp; result = true; @@ -174,13 +169,13 @@ bool CompositeCutter::facetDrop(CLPoint &cl, const Triangle &t) const { //******** edge **************************************************** */ bool CompositeCutter::edgeDrop(CLPoint &cl, const Triangle &t) const { bool result = false; - for (unsigned int n=0; nedgeDrop(cl_tmp,t) ) { // drop sub-cutter against edge - if ( ccValidRadius(n,cl_tmp) ) { // check if cc-point is valid + for (unsigned int n = 0; n < cutter.size(); ++n) { // loop through cutters + CLPoint cl_tmp = cl + Point(0, 0, zoffset[n]); + CCPoint *cc_tmp; + if (cutter[n]->edgeDrop(cl_tmp, t)) { // drop sub-cutter against edge + if (ccValidRadius(n, cl_tmp)) { // check if cc-point is valid cc_tmp = new CCPoint(*cl_tmp.cc); - if (cl.liftZ( cl_tmp.z - zoffset[n] ) ) { // we need to lift the cutter + if (cl.liftZ(cl_tmp.z - zoffset[n])) { // we need to lift the cutter cc_tmp->type = EDGE; cl.cc = cc_tmp; result = true; @@ -193,24 +188,24 @@ bool CompositeCutter::edgeDrop(CLPoint &cl, const Triangle &t) const { return result; } -bool CompositeCutter::vertexPush(const Fiber& f, Interval& i, const Triangle& t) const { +bool CompositeCutter::vertexPush(const Fiber &f, Interval &i, const Triangle &t) const { bool result = false; - std::vector< std::pair > contacts; - for (unsigned int n=0; n> contacts; + for (unsigned int n = 0; n < cutter.size(); ++n) { Interval ci; Fiber cf(f); cf.p1.z = f.p1.z + zoffset[n]; cf.p2.z = f.p2.z + zoffset[n]; // raised/lowered fiber to push along - if ( cutter[n]->vertexPush(cf,ci,t) ) { - if ( ccValidHeight( n, ci.upper_cc, f ) ) - contacts.push_back( std::pair(ci.upper, ci.upper_cc) ); - if ( ccValidHeight( n, ci.lower_cc, f ) ) - contacts.push_back( std::pair(ci.lower, ci.lower_cc) ); + if (cutter[n]->vertexPush(cf, ci, t)) { + if (ccValidHeight(n, ci.upper_cc, f)) + contacts.push_back(std::pair(ci.upper, ci.upper_cc)); + if (ccValidHeight(n, ci.lower_cc, f)) + contacts.push_back(std::pair(ci.lower, ci.lower_cc)); } } - for( unsigned int n=0; n > contacts; - for (unsigned int n=0; n> contacts; + for (unsigned int n = 0; n < cutter.size(); ++n) { Interval ci; Fiber cf(f); cf.p1.z = f.p1.z + zoffset[n]; cf.p2.z = f.p2.z + zoffset[n]; // raised/lowered fiber to push along - if ( cutter[n]->facetPush(cf,ci,t) ) { - if ( ccValidHeight( n, ci.upper_cc, f ) ) - contacts.push_back( std::pair(ci.upper, ci.upper_cc) ); - if ( ccValidHeight( n, ci.lower_cc, f ) ) - contacts.push_back( std::pair(ci.lower, ci.lower_cc) ); + if (cutter[n]->facetPush(cf, ci, t)) { + if (ccValidHeight(n, ci.upper_cc, f)) + contacts.push_back(std::pair(ci.upper, ci.upper_cc)); + if (ccValidHeight(n, ci.lower_cc, f)) + contacts.push_back(std::pair(ci.lower, ci.lower_cc)); } } - for( unsigned int n=0; n > contacts; - for (unsigned int n=0; n> contacts; + for (unsigned int n = 0; n < cutter.size(); ++n) { Interval ci; // interval for this cutter Fiber cf(f); // fiber for this cutter cf.p1.z = f.p1.z + zoffset[n]; cf.p2.z = f.p2.z + zoffset[n]; // raised/lowered fiber to push along - if ( cutter[n]->edgePush(cf,ci,t) ) { - if ( ccValidHeight( n, ci.upper_cc, f ) ) - contacts.push_back( std::pair(ci.upper, ci.upper_cc) ); - if ( ccValidHeight( n, ci.lower_cc, f ) ) - contacts.push_back( std::pair(ci.lower, ci.lower_cc) ); + if (cutter[n]->edgePush(cf, ci, t)) { + if (ccValidHeight(n, ci.upper_cc, f)) + contacts.push_back(std::pair(ci.upper, ci.upper_cc)); + if (ccValidHeight(n, ci.lower_cc, f)) + contacts.push_back(std::pair(ci.lower, ci.lower_cc)); } } - for( unsigned int n=0; nstr() << "\n"; - o << " radius["<< n << "]="<< radiusvec[n] << "\n"; - o << " height["<< n << "]="<< heightvec[n] << "\n"; - o << " zoffset["<< n << "]="<< zoffset[n] << "\n"; + o << " radius[" << n << "]=" << radiusvec[n] << "\n"; + o << " height[" << n << "]=" << heightvec[n] << "\n"; + o << " zoffset[" << n << "]=" << zoffset[n] << "\n"; } return o.str(); } - //******** actual Composite-cutters ******************************* */ - // only constructors required, drop-cutter and push-cutter calls handled by base-class // TESTING CompCylCutter::CompCylCutter(double diam2, double clength) { - MillingCutter* shaft = new CylCutter(diam2, clength ); - addCutter( *shaft, diam2/2.0, clength , 0.0 ); + MillingCutter *shaft = new CylCutter(diam2, clength); + addCutter(*shaft, diam2 / 2.0, clength, 0.0); length = clength; } // TESTING CompBallCutter::CompBallCutter(double diam2, double clength) { - MillingCutter* shaft = new BallCutter(diam2, clength ); - addCutter( *shaft, diam2/2.0, clength , 0.0 ); + MillingCutter *shaft = new BallCutter(diam2, clength); + addCutter(*shaft, diam2 / 2.0, clength, 0.0); length = clength; } - CylConeCutter::CylConeCutter(double diam1, double diam2, double angle) { - MillingCutter* cyl = new CylCutter(diam1, 1 ); - MillingCutter* cone = new ConeCutter(diam2, angle); - MillingCutter* shaft = new CylCutter(diam2, 20 ); // FIXME: dummy height + MillingCutter *cyl = new CylCutter(diam1, 1); + MillingCutter *cone = new ConeCutter(diam2, angle); + MillingCutter *shaft = new CylCutter(diam2, 20); // FIXME: dummy height - double cone_offset= - (diam1/2)/tan(angle); + double cone_offset = -(diam1 / 2) / tan(angle); double cyl_height = 0.0; - double cone_height = (diam2/2.0)/tan(angle) + cone_offset; + double cone_height = (diam2 / 2.0) / tan(angle) + cone_offset; - addCutter( *cyl, diam1/2.0, cyl_height, 0.0 ); - addCutter( *cone, diam2/2.0, cone_height, cone_offset ); - addCutter( *shaft, diam2/2.0, (diam2/2.0)/tan(angle) + 20 , cone_height ); + addCutter(*cyl, diam1 / 2.0, cyl_height, 0.0); + addCutter(*cone, diam2 / 2.0, cone_height, cone_offset); + addCutter(*shaft, diam2 / 2.0, (diam2 / 2.0) / tan(angle) + 20, cone_height); length = cyl_height + cone_height + 10; // Arbitrary 10 here! } - BallConeCutter::BallConeCutter(double diam1, double diam2, double angle) { - MillingCutter* c1 = new BallCutter(diam1, 1); // at offset zero - MillingCutter* c2 = new ConeCutter(diam2, angle); - MillingCutter* shaft = new CylCutter(diam2, 20); // FIXME: length - - double radius1 = diam1/2.0; - double radius2 = diam2/2.0; - double rcontact = radius1*cos(angle); - double height1 = radius1 - sqrt( square(radius1)-square(rcontact) ); - double cone_offset = - ( (rcontact)/tan(angle) - height1 ); - double height2 = radius2/tan(angle) + cone_offset; + MillingCutter *c1 = new BallCutter(diam1, 1); // at offset zero + MillingCutter *c2 = new ConeCutter(diam2, angle); + MillingCutter *shaft = new CylCutter(diam2, 20); // FIXME: length + + double radius1 = diam1 / 2.0; + double radius2 = diam2 / 2.0; + double rcontact = radius1 * cos(angle); + double height1 = radius1 - sqrt(square(radius1) - square(rcontact)); + double cone_offset = -((rcontact) / tan(angle) - height1); + double height2 = radius2 / tan(angle) + cone_offset; double shaft_offset = height2; // cutter, radivec, heightvec, zoffset - addCutter( *c1, rcontact, height1, 0.0 ); - addCutter( *c2, diam2/2.0, height2, cone_offset ); - addCutter( *shaft, diam2/2.0, height2+20, shaft_offset ); + addCutter(*c1, rcontact, height1, 0.0); + addCutter(*c2, diam2 / 2.0, height2, cone_offset); + addCutter(*shaft, diam2 / 2.0, height2 + 20, shaft_offset); length = 30; } BullConeCutter::BullConeCutter(double diam1, double radius1, double diam2, double angle) { - MillingCutter* c1 = new BullCutter(diam1, radius1, 1.0); // at offset zero - MillingCutter* c2 = new ConeCutter(diam2, angle); - MillingCutter* shaft = new CylCutter(diam2, 20); - - double h1 = radius1*sin(angle); // the contact point is this much down from the toroid-ring - double rad = sqrt( square(radius1) - square(h1) ); - double rcontact = (diam1/2.0) - radius1 + rad; // radius of the contact-ring - double cone_offset= - ( rcontact/tan(angle) - (radius1-h1)); + MillingCutter *c1 = new BullCutter(diam1, radius1, 1.0); // at offset zero + MillingCutter *c2 = new ConeCutter(diam2, angle); + MillingCutter *shaft = new CylCutter(diam2, 20); + + double h1 = radius1 * sin(angle); // the contact point is this much down from the toroid-ring + double rad = sqrt(square(radius1) - square(h1)); + double rcontact = (diam1 / 2.0) - radius1 + rad; // radius of the contact-ring + double cone_offset = -(rcontact / tan(angle) - (radius1 - h1)); double height1 = radius1 - h1; - double height2 = (diam2/2.0)/tan(angle) + cone_offset; + double height2 = (diam2 / 2.0) / tan(angle) + cone_offset; double shaft_offset = height2; - addCutter( *c1, rcontact, height1, 0.0 ); - addCutter( *c2, diam2/2.0, height2, cone_offset ); - addCutter( *shaft, diam2/2.0, height2+20, shaft_offset ); - length=30; + addCutter(*c1, rcontact, height1, 0.0); + addCutter(*c2, diam2 / 2.0, height2, cone_offset); + addCutter(*shaft, diam2 / 2.0, height2 + 20, shaft_offset); + length = 30; } -ConeConeCutter::ConeConeCutter(double diam1, double angle1, double diam2, double angle2) -{ - MillingCutter* c1 = new ConeCutter(diam1, angle1); // at offset zero - MillingCutter* c2 = new ConeCutter(diam2, angle2); - MillingCutter* shaft = new CylCutter(diam2, 20); +ConeConeCutter::ConeConeCutter(double diam1, double angle1, double diam2, double angle2) { + MillingCutter *c1 = new ConeCutter(diam1, angle1); // at offset zero + MillingCutter *c2 = new ConeCutter(diam2, angle2); + MillingCutter *shaft = new CylCutter(diam2, 20); - double height1 = (diam1/2.0)/tan(angle1); - double tmp = (diam1/2.0)/tan(angle2); - double cone_offset= - ( tmp-height1); - double height2 = (diam2/2.0)/tan(angle2) + cone_offset; + double height1 = (diam1 / 2.0) / tan(angle1); + double tmp = (diam1 / 2.0) / tan(angle2); + double cone_offset = -(tmp - height1); + double height2 = (diam2 / 2.0) / tan(angle2) + cone_offset; double shaft_offset = height2; - addCutter( *c1, diam1/2.0, height1, 0.0 ); - addCutter( *c2, diam2/2.0, height2, cone_offset ); - addCutter( *shaft, diam2/2.0, height2+20, shaft_offset ); - length=30; + addCutter(*c1, diam1 / 2.0, height1, 0.0); + addCutter(*c2, diam2 / 2.0, height2, cone_offset); + addCutter(*shaft, diam2 / 2.0, height2 + 20, shaft_offset); + length = 30; } -} // end namespace +} // namespace ocl // end file compositecutter.cpp diff --git a/src/cutters/compositecutter.hpp b/src/cutters/compositecutter.hpp index ff088a6b..8b848fb6 100644 --- a/src/cutters/compositecutter.hpp +++ b/src/cutters/compositecutter.hpp @@ -1,23 +1,23 @@ /* $Id$ - * + * * Copyright (c) 2010-2011 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef COMPOSITE_CUTTER_H #define COMPOSITE_CUTTER_H @@ -28,129 +28,125 @@ #include "millingcutter.hpp" -namespace ocl -{ +namespace ocl { /// \brief a CompositeCutter is composed one or more MillingCutters /// the cutters are stored in a vector *cutter* and their axial offsets /// from eachother in *zoffset*. The different cutters apply in different -/// radial regions. cutter[0] from r=0 to r=radius[0] after that -/// cutter[1] from r=radius[0] to r=radius[1] and so on. +/// radial regions. cutter[0] from r=0 to r=radius[0] after that +/// cutter[1] from r=radius[0] to r=radius[1] and so on. class CompositeCutter : public MillingCutter { - public: - /// create an empty CompositeCutter - CompositeCutter(); - /// add a MillingCutter to this CompositeCutter - /// the cutter is valid from the previous radius out to the given radius - /// and its axial offset is given by zoffset - void addCutter(MillingCutter& c, double radius, double height, double zoff); - - - - MillingCutter* offsetCutter(double d) const; - - /// CompositeCutter can not use the base-class facetDrop, instead we here - /// call facetDrop() on each cutter in turn, and pick the valid CC/CL point - /// as the result for the CompositeCutter - bool facetDrop(CLPoint &cl, const Triangle &t) const; - /// call edgeDrop on each cutter and pick the correct (highest valid CL-point) result - bool edgeDrop(CLPoint &cl, const Triangle &t) const; - - std::string str() const; - protected: - - bool vertexPush(const Fiber& f, Interval& i, const Triangle& t) const; - bool facetPush(const Fiber& f, Interval& i, const Triangle& t) const; - bool edgePush(const Fiber& f, Interval& i, const Triangle& t) const; - - /// convert input radius r to cutter index - unsigned int radius_to_index(double r) const; - unsigned int height_to_index(double h) const; - - /// return true if radius=r belongs to cutter n - bool validRadius(unsigned int n, double r) const; - bool validHeight(unsigned int n, double h) const; - - double height(double r) const; - double width(double h) const; - - /// return true if cl.cc is within the radial range of cutter n - /// for cutter n the valid radial distance from cl is - /// between radiusvec[n-1] and radiusvec[n] - bool ccValidRadius(unsigned int n, CLPoint& cl) const; - - bool ccValidHeight(unsigned int n, CCPoint& cc, const Fiber& f) const; - - /// vector that holds the radiuses of the different cutters. - /// cutter[0] is valid from r=0 to r=radiusvec[0] - /// cutter[1] is valid from r=radiusvec[0] to r=radiusvec[1] - /// etc - std::vector radiusvec; // vector of radiuses - /// vector for cutter heights - /// cutter[0] is valid in h = [0, heihgtvec[0] ] - /// cutter[1] is valid in h = [ heightvec[0], heihgtvec[1] ] - std::vector heightvec; // vector of heights - /// vector of the axial offsets - std::vector zoffset; // vector of z-offset values for the cutters - /// vector of cutters in this CompositeCutter - std::vector cutter; // vector of pointers to cutters + public: + /// create an empty CompositeCutter + CompositeCutter(); + /// add a MillingCutter to this CompositeCutter + /// the cutter is valid from the previous radius out to the given radius + /// and its axial offset is given by zoffset + void addCutter(MillingCutter &c, double radius, double height, double zoff); + + MillingCutter *offsetCutter(double d) const; + + /// CompositeCutter can not use the base-class facetDrop, instead we here + /// call facetDrop() on each cutter in turn, and pick the valid CC/CL point + /// as the result for the CompositeCutter + bool facetDrop(CLPoint &cl, const Triangle &t) const; + /// call edgeDrop on each cutter and pick the correct (highest valid CL-point) result + bool edgeDrop(CLPoint &cl, const Triangle &t) const; + + std::string str() const; + + protected: + bool vertexPush(const Fiber &f, Interval &i, const Triangle &t) const; + bool facetPush(const Fiber &f, Interval &i, const Triangle &t) const; + bool edgePush(const Fiber &f, Interval &i, const Triangle &t) const; + + /// convert input radius r to cutter index + unsigned int radius_to_index(double r) const; + unsigned int height_to_index(double h) const; + + /// return true if radius=r belongs to cutter n + bool validRadius(unsigned int n, double r) const; + bool validHeight(unsigned int n, double h) const; + + double height(double r) const; + double width(double h) const; + + /// return true if cl.cc is within the radial range of cutter n + /// for cutter n the valid radial distance from cl is + /// between radiusvec[n-1] and radiusvec[n] + bool ccValidRadius(unsigned int n, CLPoint &cl) const; + + bool ccValidHeight(unsigned int n, CCPoint &cc, const Fiber &f) const; + + /// vector that holds the radiuses of the different cutters. + /// cutter[0] is valid from r=0 to r=radiusvec[0] + /// cutter[1] is valid from r=radiusvec[0] to r=radiusvec[1] + /// etc + std::vector radiusvec; // vector of radiuses + /// vector for cutter heights + /// cutter[0] is valid in h = [0, heihgtvec[0] ] + /// cutter[1] is valid in h = [ heightvec[0], heihgtvec[1] ] + std::vector heightvec; // vector of heights + /// vector of the axial offsets + std::vector zoffset; // vector of z-offset values for the cutters + /// vector of cutters in this CompositeCutter + std::vector cutter; // vector of pointers to cutters }; /// a composite cutter for testing, consisting only of a cylindrical cutter class CompCylCutter : public CompositeCutter { - public: - CompCylCutter() {} - CompCylCutter(double diam, double length); + public: + CompCylCutter() {} + CompCylCutter(double diam, double length); }; /// for testing, a single ballcutter class CompBallCutter : public CompositeCutter { - public: - CompBallCutter() {} - CompBallCutter(double diam, double length); + public: + CompBallCutter() {} + CompBallCutter(double diam, double length); }; /// \brief CompositeCutter with a cylindrical/flat central part of diameter diam1 /// and a conical outer part sloping at angle, with a max diameter diam2 class CylConeCutter : public CompositeCutter { - public: - CylConeCutter() {}; // dummy, required(?) by python wrapper - /// create cylconecutter - CylConeCutter(double diam1, double diam2, double angle); + public: + CylConeCutter(){}; // dummy, required(?) by python wrapper + /// create cylconecutter + CylConeCutter(double diam1, double diam2, double angle); }; /// \brief CompositeCutter with a spherical central part of diameter diam1 /// and a conical outer part sloping at angle, with a max diameter diam2 /// the cone is positioned so that the tangent of the cone matches the tangent of the sphere class BallConeCutter : public CompositeCutter { - public: - BallConeCutter() {}; // dummy, required(?) by python wrapper - /// create ballconecutter - BallConeCutter(double diam1, double diam2, double angle); + public: + BallConeCutter(){}; // dummy, required(?) by python wrapper + /// create ballconecutter + BallConeCutter(double diam1, double diam2, double angle); }; -/// \brief CompositeCutter with a toroidal central part of diameter diam1 +/// \brief CompositeCutter with a toroidal central part of diameter diam1 /// and corner radius radius1 /// The outer part is conical sloping at angle, with a max diameter diam2 /// the cone is positioned so that the tangent of the cone matches the tangent of the torus class BullConeCutter : public CompositeCutter { - public: - BullConeCutter() {}; // dummy, required(?) by python wrapper - /// create bullconecutter - BullConeCutter(double diam1, double radius1, double diam2, double angle); + public: + BullConeCutter(){}; // dummy, required(?) by python wrapper + /// create bullconecutter + BullConeCutter(double diam1, double radius1, double diam2, double angle); }; -/// \brief CompositeCutter with a conical central part with diam1/angle1 +/// \brief CompositeCutter with a conical central part with diam1/angle1 /// and a conical outer part with diam2/angle2 /// we assume angle2 < angle1 and diam2 > diam1. class ConeConeCutter : public CompositeCutter { - public: - ConeConeCutter() {}; // dummy, required(?) by python wrapper - /// create cone-cone cutter with lower cone (diam1,angle1) and upper cone (diam2,angle2) - /// we assume angle2 < angle1 and diam2 > diam1. - ConeConeCutter(double diam1, double angle1, double diam2, double angle2); + public: + ConeConeCutter(){}; // dummy, required(?) by python wrapper + /// create cone-cone cutter with lower cone (diam1,angle1) and upper cone (diam2,angle2) + /// we assume angle2 < angle1 and diam2 > diam1. + ConeConeCutter(double diam1, double angle1, double diam2, double angle2); }; - -} // end namespace +} // namespace ocl #endif diff --git a/src/cutters/conecutter.cpp b/src/cutters/conecutter.cpp index 2cd9370d..17fa6a26 100644 --- a/src/cutters/conecutter.cpp +++ b/src/cutters/conecutter.cpp @@ -1,23 +1,23 @@ /* $Id$ - * + * * Copyright (c) 2010-2011 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #include #include @@ -25,56 +25,51 @@ #include -#include "conecutter.hpp" #include "compositecutter.hpp" // for offsetCutter() +#include "conecutter.hpp" #include "numeric.hpp" -namespace ocl -{ +namespace ocl { -ConeCutter::ConeCutter() { - assert(0); -} +ConeCutter::ConeCutter() { assert(0); } ConeCutter::ConeCutter(double d, double a, double l) { diameter = d; - radius = d/2.0; + radius = d / 2.0; angle = a; - assert( angle > 0.0 ); - length = radius/tan(angle) + l; - center_height = radius/tan(angle); - assert( center_height > 0.0 ); + assert(angle > 0.0); + length = radius / tan(angle) + l; + center_height = radius / tan(angle); + assert(center_height > 0.0); xy_normal_length = radius; normal_length = 0.0; } double ConeCutter::height(double r) const { - assert( tan(angle) > 0.0 ); // guard against division by zero - return r/tan(angle); + assert(tan(angle) > 0.0); // guard against division by zero + return r / tan(angle); } double ConeCutter::width(double h) const { // grows from zero up to radius // above that (cutter shaft) return radius - return (h abs(mu) there is contact with the circular edge at +/- xu double ccu; - if ( hyperbola_case ) { - ccu = sign(m) * sqrt( square(radius)*square(m)*square(d) / (square(length) -square(radius)*square(m) ) ); - } else { - ccu = sign(m)*xu; - } - Point cc_tmp( ccu, d, 0.0); // cc-point in the XY plane - cc_tmp.z_projectOntoEdge(u1,u2); + if (hyperbola_case) { + ccu = sign(m) * sqrt(square(radius) * square(m) * square(d) / (square(length) - square(radius) * square(m))); + } else { + ccu = sign(m) * xu; + } + Point cc_tmp(ccu, d, 0.0); // cc-point in the XY plane + cc_tmp.z_projectOntoEdge(u1, u2); double cl_z; - if ( hyperbola_case ) { // 1) zc = zp - Lc + (R - sqrt(xp^2 + d^2)) / tan(beta2) - cl_z = cc_tmp.z - center_height + (radius-sqrt(square(ccu) + square(d)))/ tan(angle); - } else { // 2) zc = zp - Lc + if (hyperbola_case) { // 1) zc = zp - Lc + (R - sqrt(xp^2 + d^2)) / tan(beta2) + cl_z = cc_tmp.z - center_height + (radius - sqrt(square(ccu) + square(d))) / tan(angle); + } else { // 2) zc = zp - Lc cl_z = cc_tmp.z - center_height; // case where we hit the edge of the cone - } - return CC_CLZ_Pair( ccu , cl_z); + } + return CC_CLZ_Pair(ccu, cl_z); } -bool ConeCutter::facetPush(const Fiber& fib, Interval& i, const Triangle& t) const { +bool ConeCutter::facetPush(const Fiber &fib, Interval &i, const Triangle &t) const { // push two objects: tip, and base-circle bool result = false; - if ( generalFacetPush( 0, 0, 0, fib, i, t) ) // TIP + if (generalFacetPush(0, 0, 0, fib, i, t)) // TIP result = true; - // normal_length, center_height, xy_normal_length, fiber, interval, triangle - if ( generalFacetPush( 0, this->center_height, this->xy_normal_length , fib, i ,t) ) // BASE + // normal_length, center_height, xy_normal_length, fiber, interval, triangle + if (generalFacetPush(0, this->center_height, this->xy_normal_length, fib, i, t)) // BASE result = true; return result; } // cone is pushed along Fiber f into contact with edge p1-p2 -bool ConeCutter::generalEdgePush(const Fiber& f, Interval& i, const Point& p1, const Point& p2) const { +bool ConeCutter::generalEdgePush(const Fiber &f, Interval &i, const Point &p1, const Point &p2) const { bool result = false; - - if ( isZero_tol(p2.z-p1.z) ) // guard against horizontal edge + + if (isZero_tol(p2.z - p1.z)) // guard against horizontal edge return result; - assert( (p2.z-p1.z) != 0.0 ); + assert((p2.z - p1.z) != 0.0); // idea: as the ITO-cone slides along the edge it will pierce a z-plane at the height of the fiber // the shaped of the pierced area is either a circle if the edge is steep // or a 'half-circle' + cone shape if the edge is shallow (ice-cream cone...) @@ -160,149 +156,144 @@ bool ConeCutter::generalEdgePush(const Fiber& f, Interval& i, const Point& p1, // this is where the ITO cone pierces the z-plane of the fiber // edge-line: p1+t*(p2-p1) = zheight - // => t = (zheight - p1)/ (p2-p1) - double t_tip = (f.p1.z - p1.z) / (p2.z-p1.z); - Point p_tip = p1 + t_tip*(p2-p1); - assert( isZero_tol( abs(p_tip.z-f.p1.z) ) ); // p_tip should be in plane of fiber - + // => t = (zheight - p1)/ (p2-p1) + double t_tip = (f.p1.z - p1.z) / (p2.z - p1.z); + Point p_tip = p1 + t_tip * (p2 - p1); + assert(isZero_tol(abs(p_tip.z - f.p1.z))); // p_tip should be in plane of fiber + // this is where the ITO cone base exits the plane - double t_base = (f.p1.z+center_height - p1.z) / (p2.z-p1.z); - Point p_base = p1 + t_base*(p2-p1); + double t_base = (f.p1.z + center_height - p1.z) / (p2.z - p1.z); + Point p_base = p1 + t_base * (p2 - p1); p_base.z = f.p1.z; // project to plane of fiber - double L = (p_base-p_tip).xyNorm(); - - //if ( L <= radius ){ // this is where the ITO-slice is a circle - // find intersection points, if any, between the fiber and the circle - // fiber is f.p1 - f.p2 - // circle is centered at p_base - double d = p_base.xyDistanceToLine(f.p1, f.p2); - if ( d <= radius ) { - // we know there is an intersection point. - // http://mathworld.wolfram.com/Circle-LineIntersection.html - - // subtract circle center, math is for circle centered at (0,0) - double dx = f.p2.x - f.p1.x; - double dy = f.p2.y - f.p1.y; - double dr = sqrt( square(dx) + square(dy) ); - double det = (f.p1.x-p_base.x) * (f.p2.y-p_base.y) - (f.p2.x-p_base.x) * (f.p1.y-p_base.y); - - // intersection given by: - // x = det*dy +/- sign(dy) * dx * sqrt( r^2 dr^2 - det^2 ) / dr^2 - // y = -det*dx +/- abs(dy) * sqrt( r^2 dr^2 - det^2 ) / dr^2 - - double discr = square(radius) * square(dr) - square(det); - if (discr >= 0.0 ) { - if ( discr == 0.0 ) { // tangent case - double x_tang = ( det*dy )/ square(dr); - double y_tang = -( det*dx )/ square(dr); - Point p_tang(x_tang+p_base.x, y_tang+p_base.y); // translate back from (0,0) system! - double t_tang = f.tval( p_tang ); - if ( circle_CC( t_tang, p1, p2, f, i) ) { - result = true; - } - } else { - // two intersection points with the base-circle - double x_pos = ( det*dy + sign(dy) * dx * sqrt( discr ) ) / square(dr); - double y_pos = ( -det*dx + fabs(dy) * sqrt( discr ) ) / square(dr); - Point cl_pos(x_pos+p_base.x, y_pos+p_base.y); - double t_pos = f.tval( cl_pos ); - // the same with "-" sign: - double x_neg = ( det*dy - sign(dy) * dx * sqrt( discr ) ) / square(dr); - double y_neg = ( -det*dx - fabs(dy) * sqrt( discr ) ) / square(dr); - Point cl_neg(x_neg+p_base.x, y_neg+p_base.y); - double t_neg = f.tval( cl_neg ); - if ( circle_CC( t_pos, p1, p2, f, i) ) - result = true; - - if ( circle_CC( t_neg, p1, p2, f, i) ) - result = true; + double L = (p_base - p_tip).xyNorm(); + + // if ( L <= radius ){ // this is where the ITO-slice is a circle + // find intersection points, if any, between the fiber and the circle + // fiber is f.p1 - f.p2 + // circle is centered at p_base + double d = p_base.xyDistanceToLine(f.p1, f.p2); + if (d <= radius) { + // we know there is an intersection point. + // http://mathworld.wolfram.com/Circle-LineIntersection.html + // subtract circle center, math is for circle centered at (0,0) + double dx = f.p2.x - f.p1.x; + double dy = f.p2.y - f.p1.y; + double dr = sqrt(square(dx) + square(dy)); + double det = (f.p1.x - p_base.x) * (f.p2.y - p_base.y) - (f.p2.x - p_base.x) * (f.p1.y - p_base.y); + + // intersection given by: + // x = det*dy +/- sign(dy) * dx * sqrt( r^2 dr^2 - det^2 ) / dr^2 + // y = -det*dx +/- abs(dy) * sqrt( r^2 dr^2 - det^2 ) / dr^2 + + double discr = square(radius) * square(dr) - square(det); + if (discr >= 0.0) { + if (discr == 0.0) { // tangent case + double x_tang = (det * dy) / square(dr); + double y_tang = -(det * dx) / square(dr); + Point p_tang(x_tang + p_base.x, y_tang + p_base.y); // translate back from (0,0) system! + double t_tang = f.tval(p_tang); + if (circle_CC(t_tang, p1, p2, f, i)) { + result = true; } + } else { + // two intersection points with the base-circle + double x_pos = (det * dy + sign(dy) * dx * sqrt(discr)) / square(dr); + double y_pos = (-det * dx + fabs(dy) * sqrt(discr)) / square(dr); + Point cl_pos(x_pos + p_base.x, y_pos + p_base.y); + double t_pos = f.tval(cl_pos); + // the same with "-" sign: + double x_neg = (det * dy - sign(dy) * dx * sqrt(discr)) / square(dr); + double y_neg = (-det * dx - fabs(dy) * sqrt(discr)) / square(dr); + Point cl_neg(x_neg + p_base.x, y_neg + p_base.y); + double t_neg = f.tval(cl_neg); + if (circle_CC(t_pos, p1, p2, f, i)) + result = true; + + if (circle_CC(t_neg, p1, p2, f, i)) + result = true; } } - + } + //} // circle-case - - if ( L > radius ) { - // ITO-slice is cone + "half-circle" + + if (L > radius) { + // ITO-slice is cone + "half-circle" // lines from p_tip to tangent points of the base-circle - + // this page has an analytic solution: // http://mathworld.wolfram.com/CircleTangentLine.html // this page has a geometric construction: // http://www.mathopenref.com/consttangents.html - + // circle p_base, radius // top p_tip - + // tangent point at intersection of base-circle with this circle: - Point p_mid = 0.5*( p_base + p_tip ); + Point p_mid = 0.5 * (p_base + p_tip); p_mid.z = f.p1.z; - double r_tang = L/2; - + double r_tang = L / 2; + // circle-circle intersection to find tangent-points // three cases: no intersection point // one intersection point // two intersection points - //d is the distance between the circle centers - Point pd = p_mid - p_base; + // d is the distance between the circle centers + Point pd = p_mid - p_base; pd.z = 0; - double dist = pd.xyNorm(); //distance between the circles - - //Check for special cases which do not lead to solutions we want - bool case1 = ( isZero_tol( dist ) && isZero_tol( fabs(radius - r_tang) ) ); - bool case2 = (dist > (radius + r_tang) ); //no solution. circles do not intersect - bool case3 = ( dist < fabs(radius - r_tang)); //no solution. one circle is contained in the other - bool case4 = ( isZero_tol( dist - (radius+r_tang) ) ); // tangent case - if (case1 || case2 || case3 || case4 ) { - + double dist = pd.xyNorm(); // distance between the circles + + // Check for special cases which do not lead to solutions we want + bool case1 = (isZero_tol(dist) && isZero_tol(fabs(radius - r_tang))); + bool case2 = (dist > (radius + r_tang)); // no solution. circles do not intersect + bool case3 = (dist < fabs(radius - r_tang)); // no solution. one circle is contained in the other + bool case4 = (isZero_tol(dist - (radius + r_tang))); // tangent case + if (case1 || case2 || case3 || case4) { + } else { // here we know we have two solutions. - //Determine the distance from point 0 to point 2 - // law of cosines (http://en.wikipedia.org/wiki/Law_of_cosines) - // rt^2 = d^2 + r^2 -2*d*r*cos(gamma) - // so cos(gamma) = (rt^2-d^2-r^2)/ -(2*d*r) - // and the sought distance is - // a = r*cos(gamma) = (-rt^2+d^2+r^2)/ (2*d) - double a = ( -square(r_tang) + square(radius) + square(dist) ) / (2.0 * dist); - assert( a >= 0.0 ); - - Point v2 = p_base + (a/dist)*pd; // v2 is the point where the line through the circle intersection points crosses the line between the circle centers. - //Determine the distance from v2 to either of the intersection points - double h = sqrt( square(radius) - square(a) ); - //Now determine the offsets of the intersection points from point 2 - Point ofs( -pd.y * (h / dist), pd.x * (h / dist) ); + // Determine the distance from point 0 to point 2 + // law of cosines (http://en.wikipedia.org/wiki/Law_of_cosines) + // rt^2 = d^2 + r^2 -2*d*r*cos(gamma) + // so cos(gamma) = (rt^2-d^2-r^2)/ -(2*d*r) + // and the sought distance is + // a = r*cos(gamma) = (-rt^2+d^2+r^2)/ (2*d) + double a = (-square(r_tang) + square(radius) + square(dist)) / (2.0 * dist); + assert(a >= 0.0); + + Point v2 = p_base + (a / dist) * pd; // v2 is the point where the line through the circle intersection + // points crosses the line between the circle centers. + // Determine the distance from v2 to either of the intersection points + double h = sqrt(square(radius) - square(a)); + // Now determine the offsets of the intersection points from point 2 + Point ofs(-pd.y * (h / dist), pd.x * (h / dist)); // now we know the tangent-points Point tang1 = v2 + ofs; Point tang2 = v2 - ofs; - if ( cone_CC( tang1, p_tip, p_base, p1, p2, f, i ) ) + if (cone_CC(tang1, p_tip, p_base, p1, p2, f, i)) result = true; - if ( cone_CC( tang2, p_tip, p_base, p1, p2, f, i ) ) + if (cone_CC(tang2, p_tip, p_base, p1, p2, f, i)) result = true; } } // end circle+cone case - + return result; } // test for intersection with the fiber and a tip-tang line // if there is an intersection in tip-tang, calculate the cc-point and update the interval -bool ConeCutter::cone_CC(const Point& tang, - const Point& tip, - const Point& base, - const Point& p1, - const Point& p2, - const Fiber& f, - Interval& i) const { - double u,t; - if ( xy_line_line_intersection( f.p1, f.p2, u, tang, tip, t) ) { - if ( (t>=0.0) && (t<=1.0) ) { - CCPoint cc_tmp = base + t*(tip-base); - cc_tmp.z_projectOntoEdge(p1,p2); +bool ConeCutter::cone_CC(const Point &tang, const Point &tip, const Point &base, const Point &p1, const Point &p2, + const Fiber &f, Interval &i) const { + double u, t; + if (xy_line_line_intersection(f.p1, f.p2, u, tang, tip, t)) { + if ((t >= 0.0) && (t <= 1.0)) { + CCPoint cc_tmp = base + t * (tip - base); + cc_tmp.z_projectOntoEdge(p1, p2); cc_tmp.type = EDGE_CONE; - return i.update_ifCCinEdgeAndTrue( u, cc_tmp, p1, p2, (true) ) ; + return i.update_ifCCinEdgeAndTrue(u, cc_tmp, p1, p2, (true)); } } return false; @@ -311,12 +302,13 @@ bool ConeCutter::cone_CC(const Point& tang, // t is a position along the fiber // p1-p2 is the edge // Interval& i is updated -bool ConeCutter::circle_CC( double t, const Point& p1, const Point& p2, const Fiber& f, Interval& i) const { +bool ConeCutter::circle_CC(double t, const Point &p1, const Point &p2, const Fiber &f, Interval &i) const { // cone base circle is center_height above fiber - double t_cc = (f.p1.z+center_height - p1.z) / (p2.z-p1.z); // t-parameter of the cc-point, center_height above fiber - CCPoint cc_tmp = p1 + t_cc*(p2-p1); // cc-point on the edge + double t_cc = + (f.p1.z + center_height - p1.z) / (p2.z - p1.z); // t-parameter of the cc-point, center_height above fiber + CCPoint cc_tmp = p1 + t_cc * (p2 - p1); // cc-point on the edge cc_tmp.type = EDGE_CONE_BASE; - return i.update_ifCCinEdgeAndTrue( t, cc_tmp, p1, p2, (true) ); + return i.update_ifCCinEdgeAndTrue(t, cc_tmp, p1, p2, (true)); } std::string ConeCutter::str() const { @@ -325,10 +317,10 @@ std::string ConeCutter::str() const { return o.str(); } -std::ostream& operator<<(std::ostream &stream, ConeCutter c) { - stream << "ConeCutter (d=" << c.diameter << ", angle=" << c.angle << ", L=" << c.length << ")"; - return stream; +std::ostream &operator<<(std::ostream &stream, ConeCutter c) { + stream << "ConeCutter (d=" << c.diameter << ", angle=" << c.angle << ", L=" << c.length << ")"; + return stream; } -} // end namespace +} // namespace ocl // end file conecutter.cpp diff --git a/src/cutters/conecutter.hpp b/src/cutters/conecutter.hpp index 8e690731..2f191098 100644 --- a/src/cutters/conecutter.hpp +++ b/src/cutters/conecutter.hpp @@ -1,23 +1,23 @@ /* $Id$ - * + * * Copyright (c) 2010-2011 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef CONE_CUTTER_HPP #define CONE_CUTTER_HPP @@ -27,49 +27,43 @@ #include "millingcutter.hpp" -namespace ocl -{ +namespace ocl { -/// \brief Conical MillingCutter +/// \brief Conical MillingCutter /// -/// cone defined by diameter and the cone half-angle(in radians). sharp tip. +/// cone defined by diameter and the cone half-angle(in radians). sharp tip. /// 60 degrees or 90 degrees are common class ConeCutter : public MillingCutter { - public: - ConeCutter(); - /// create a ConeCutter with specified maximum diameter and cone-angle - /// for a 90-degree cone specify the half-angle angle= pi/4 - ConeCutter(double d, double angle, double l=10); - /// offset of ConeCutter is BallConeCutter (should be Ball-Cone-Bull??) - MillingCutter* offsetCutter(double d) const; - /// Cone facet-drop is special, since we can make contact with either the tip or the circular rim - bool facetDrop(CLPoint &cl, const Triangle &t) const; - /// string repr - friend std::ostream& operator<<(std::ostream &stream, ConeCutter c); - std::string str() const; - - protected: - CC_CLZ_Pair singleEdgeDropCanonical(const Point& u1, const Point& u2) const; - - bool facetPush(const Fiber& fib, Interval& i, const Triangle& t) const; - - bool generalEdgePush(const Fiber& f, Interval& i, const Point& p1, const Point& p2) const; - - bool circle_CC( double t, const Point& p1, const Point& p2, const Fiber& f, Interval& i) const; - bool cone_CC(const Point& tang, - const Point& tip, - const Point& base, - const Point& p1, - const Point& p2, - const Fiber& f, - Interval& i) const; - - double height(double r) const; - double width(double h) const; - /// the half-angle of the cone, in radians - double angle; + public: + ConeCutter(); + /// create a ConeCutter with specified maximum diameter and cone-angle + /// for a 90-degree cone specify the half-angle angle= pi/4 + ConeCutter(double d, double angle, double l = 10); + /// offset of ConeCutter is BallConeCutter (should be Ball-Cone-Bull??) + MillingCutter *offsetCutter(double d) const; + /// Cone facet-drop is special, since we can make contact with either the tip or the circular rim + bool facetDrop(CLPoint &cl, const Triangle &t) const; + /// string repr + friend std::ostream &operator<<(std::ostream &stream, ConeCutter c); + std::string str() const; + + protected: + CC_CLZ_Pair singleEdgeDropCanonical(const Point &u1, const Point &u2) const; + + bool facetPush(const Fiber &fib, Interval &i, const Triangle &t) const; + + bool generalEdgePush(const Fiber &f, Interval &i, const Point &p1, const Point &p2) const; + + bool circle_CC(double t, const Point &p1, const Point &p2, const Fiber &f, Interval &i) const; + bool cone_CC(const Point &tang, const Point &tip, const Point &base, const Point &p1, const Point &p2, + const Fiber &f, Interval &i) const; + + double height(double r) const; + double width(double h) const; + /// the half-angle of the cone, in radians + double angle; }; -} // end ocl namespace +} // namespace ocl #endif // end conecutter.hpp diff --git a/src/cutters/cylcutter.cpp b/src/cutters/cylcutter.cpp index f08d6dc9..9b33bb85 100644 --- a/src/cutters/cylcutter.cpp +++ b/src/cutters/cylcutter.cpp @@ -1,23 +1,23 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #include #include @@ -25,21 +25,22 @@ #include -#include "cylcutter.hpp" #include "bullcutter.hpp" // for offsetCutter() +#include "cylcutter.hpp" #include "numeric.hpp" -namespace ocl -{ +namespace ocl { CylCutter::CylCutter() { // std::cout << " usage: CylCutter( double diameter, double length ) \n"; } CylCutter::CylCutter(double d, double l) { - diameter= d; assert( d > 0.0); - radius= d/2.0; - length = l; assert( l > 0.0 ); + diameter = d; + assert(d > 0.0); + radius = d / 2.0; + length = l; + assert(l > 0.0); xy_normal_length = radius; normal_length = 0.0; center_height = 0.0; @@ -49,13 +50,13 @@ CylCutter::CylCutter(double d, double l) { // drop-cutter facetDrop is handled by the base-class method in MillingCutter // we handle the edge-drop here. -CC_CLZ_Pair CylCutter::singleEdgeDropCanonical(const Point& u1, const Point& u2) const { +CC_CLZ_Pair CylCutter::singleEdgeDropCanonical(const Point &u1, const Point &u2) const { // along the x-axis the cc-point is at x-coord s or -s: - double s = sqrt( square( radius ) - square( u1.y ) ); - Point cc1( s, u1.y, 0); - Point cc2( -s, u1.y, 0); - cc1.z_projectOntoEdge(u1,u2); - cc2.z_projectOntoEdge(u1,u2); + double s = sqrt(square(radius) - square(u1.y)); + Point cc1(s, u1.y, 0); + Point cc2(-s, u1.y, 0); + cc1.z_projectOntoEdge(u1, u2); + cc2.z_projectOntoEdge(u1, u2); // pick the higher one double cc_u; double cl_z; @@ -66,27 +67,27 @@ CC_CLZ_Pair CylCutter::singleEdgeDropCanonical(const Point& u1, const Point& u2) cc_u = cc2.x; cl_z = cc2.z; } - return CC_CLZ_Pair( cc_u, cl_z); + return CC_CLZ_Pair(cc_u, cl_z); } -// general purpose vertexPush, delegates to this->width(h) -bool CylCutter::vertexPush(const Fiber& f, Interval& i, const Triangle& t) const { +// general purpose vertexPush, delegates to this->width(h) +bool CylCutter::vertexPush(const Fiber &f, Interval &i, const Triangle &t) const { bool result = false; - BOOST_FOREACH( const Point& p, t.p) { - if (this->singleVertexPush(f,i,p, VERTEX) ) + BOOST_FOREACH (const Point &p, t.p) { + if (this->singleVertexPush(f, i, p, VERTEX)) result = true; } Point p1, p2; - if ( t.zslice_verts(p1, p2, f.p1.z) ) { + if (t.zslice_verts(p1, p2, f.p1.z)) { p1.z = f.p1.z; // z-coord should be very close to f.p1.z, but set it exactly anyway. p2.z = f.p1.z; - if ( this->singleVertexPush(f,i,p1, VERTEX_CYL) ) + if (this->singleVertexPush(f, i, p1, VERTEX_CYL)) result = true; - if (this->singleVertexPush(f,i,p2, VERTEX_CYL)) + if (this->singleVertexPush(f, i, p2, VERTEX_CYL)) result = true; } - + return result; } @@ -96,10 +97,10 @@ std::string CylCutter::str() const { return o.str(); } -std::ostream& operator<<(std::ostream &stream, CylCutter c) { - stream << "CylCutter (d=" << c.diameter << ", L=" << c.length << ")"; - return stream; +std::ostream &operator<<(std::ostream &stream, CylCutter c) { + stream << "CylCutter (d=" << c.diameter << ", L=" << c.length << ")"; + return stream; } -} // end namespace +} // namespace ocl // end file cylcutter.cpp diff --git a/src/cutters/cylcutter.hpp b/src/cutters/cylcutter.hpp index 23d7aba0..4454c48c 100644 --- a/src/cutters/cylcutter.hpp +++ b/src/cutters/cylcutter.hpp @@ -1,23 +1,23 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef CYL_CUTTER_H #define CYL_CUTTER_H @@ -26,32 +26,32 @@ #include #include -#include "millingcutter.hpp" #include "bullcutter.hpp" +#include "millingcutter.hpp" -namespace ocl -{ +namespace ocl { /// /// \brief Cylindrical MillingCutter (flat-endmill) /// /// defined by one parameter, the cutter diameter class CylCutter : public MillingCutter { - public: - CylCutter(); - /// create CylCutter with diameter d and length l - explicit CylCutter(double d, double l); - /// offset of Cylinder is BullCutter - MillingCutter* offsetCutter(double d) const {return new BullCutter(diameter+2*d, d, length+d);} - /// string repr - friend std::ostream& operator<<(std::ostream &stream, CylCutter c); - std::string str() const; - protected: - bool vertexPush(const Fiber& f, Interval& i, const Triangle& t) const; - CC_CLZ_Pair singleEdgeDropCanonical(const Point& u1, const Point& u2) const; - double height(double r) const {return ( r <= radius ) ? 0.0 : -1.0;} - double width(double h) const {return radius;} + public: + CylCutter(); + /// create CylCutter with diameter d and length l + explicit CylCutter(double d, double l); + /// offset of Cylinder is BullCutter + MillingCutter *offsetCutter(double d) const { return new BullCutter(diameter + 2 * d, d, length + d); } + /// string repr + friend std::ostream &operator<<(std::ostream &stream, CylCutter c); + std::string str() const; + + protected: + bool vertexPush(const Fiber &f, Interval &i, const Triangle &t) const; + CC_CLZ_Pair singleEdgeDropCanonical(const Point &u1, const Point &u2) const; + double height(double r) const { return (r <= radius) ? 0.0 : -1.0; } + double width(double h) const { return radius; } }; -} // end namespace +} // namespace ocl #endif diff --git a/src/cutters/ellipse.cpp b/src/cutters/ellipse.cpp index 76c88a60..34c8a908 100644 --- a/src/cutters/ellipse.cpp +++ b/src/cutters/ellipse.cpp @@ -1,178 +1,177 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ -#include + */ #include +#include #include #include - -#include "ellipse.hpp" -#include "numeric.hpp" #include "brent_zero.hpp" +#include "ellipse.hpp" #include "fiber.hpp" +#include "numeric.hpp" -namespace ocl -{ - +namespace ocl { //******** Ellipse ********************** */ -Ellipse::Ellipse(Point& centerin, double ain, double bin, double offsetin) { +Ellipse::Ellipse(Point ¢erin, double ain, double bin, double offsetin) { center = centerin; a = ain; b = bin; - assert( b > 0.0 ); - eccen = a/b; + assert(b > 0.0); + eccen = a / b; offset = offsetin; - target = Point(0,0,0); + target = Point(0, 0, 0); } -AlignedEllipse::AlignedEllipse(Point& centerin, double ain, double bin, double offsetin, Point& major, Point& minor) { +AlignedEllipse::AlignedEllipse(Point ¢erin, double ain, double bin, double offsetin, Point &major, Point &minor) { center = centerin; a = ain; // major axis of ellipse b = bin; // minor axis of ellipse - assert( b > 0.0 ); - eccen = a/b; + assert(b > 0.0); + eccen = a / b; offset = offsetin; - major_dir=major; - minor_dir=minor; + major_dir = major; + minor_dir = minor; } -Point Ellipse::ePoint1() const { - return this->ePoint(EllipsePosition1); -} +Point Ellipse::ePoint1() const { return this->ePoint(EllipsePosition1); } -Point Ellipse::ePoint2() const { - return this->ePoint(EllipsePosition2); -} +Point Ellipse::ePoint2() const { return this->ePoint(EllipsePosition2); } -Point Ellipse::oePoint1() const { - return this->oePoint(EllipsePosition1); -} +Point Ellipse::oePoint1() const { return this->oePoint(EllipsePosition1); } -Point Ellipse::oePoint2() const { - return this->oePoint(EllipsePosition2); -} +Point Ellipse::oePoint2() const { return this->oePoint(EllipsePosition2); } -Point Ellipse::ePoint(const EllipsePosition& pos) const { +Point Ellipse::ePoint(const EllipsePosition &pos) const { // (s, t) where: s^2 + t^2 = 1 // a and b are the orthogonal axes of the ellipse // point of ellipse is: center + a s + b t s=cos(theta) t=sin(theta) // tangent at point is: -a t + b s - // normal at point is: b s + a t + // normal at point is: b s + a t // point on offset-ellipse: point on ellipse + offset*normal Point p(center); - p.x += a*pos.s; // a is in X-direction - p.y += b*pos.t; // b is in Y-direction + p.x += a * pos.s; // a is in X-direction + p.y += b * pos.t; // b is in Y-direction return p; } -Point AlignedEllipse::ePoint(const EllipsePosition& pos) const { - Point p = center + a*pos.s*major_dir + b*pos.t*minor_dir; // point of ellipse is: center + a s + b t +Point AlignedEllipse::ePoint(const EllipsePosition &pos) const { + Point p = center + a * pos.s * major_dir + b * pos.t * minor_dir; // point of ellipse is: center + a s + b t return p; } +Point Ellipse::oePoint(const EllipsePosition &pos) const { + return ePoint(pos) + offset * normal(pos); // offset-point = ellipse-point + offset*normal +} -Point Ellipse::oePoint(const EllipsePosition& pos) const { - return ePoint(pos) + offset * normal(pos); // offset-point = ellipse-point + offset*normal -} - -Point AlignedEllipse::oePoint(const EllipsePosition& pos) const { - return ePoint(pos) + offset * normal(pos); // offset-point = ellipse-point + offset*normal -} +Point AlignedEllipse::oePoint(const EllipsePosition &pos) const { + return ePoint(pos) + offset * normal(pos); // offset-point = ellipse-point + offset*normal +} -Point Ellipse::normal(const EllipsePosition& pos) const { - assert( pos.isValid() ); - Point n = Point( b*pos.s, a*pos.t, 0); +Point Ellipse::normal(const EllipsePosition &pos) const { + assert(pos.isValid()); + Point n = Point(b * pos.s, a * pos.t, 0); n.normalize(); return n; -} +} -Point AlignedEllipse::normal(const EllipsePosition& pos) const { - // normal at point is: b s + a t - Point n = pos.s*b*major_dir + pos.t*a*minor_dir; +Point AlignedEllipse::normal(const EllipsePosition &pos) const { + // normal at point is: b s + a t + Point n = pos.s * b * major_dir + pos.t * a * minor_dir; n.normalize(); return n; -} - +} -#define OE_ERROR_TOLERANCE 1e-10 /// \todo magic number tolerance +#define OE_ERROR_TOLERANCE 1e-10 /// \todo magic number tolerance // #define DEBUG_SOLVER // // given a known EllipsePosition1, look for the other symmetric // solution EllipsePosition2 bool Ellipse::find_EllipsePosition2() { // a horrible horrible function... :( - assert( EllipsePosition1.isValid() ); + assert(EllipsePosition1.isValid()); double err1 = fabs(this->error(this->EllipsePosition1)); - this->EllipsePosition2.s = this->EllipsePosition1.s; // plus + this->EllipsePosition2.s = this->EllipsePosition1.s; // plus this->EllipsePosition2.t = -this->EllipsePosition1.t; // minus - if ( fabs(this->error(this->EllipsePosition2)) < err1+OE_ERROR_TOLERANCE) { - if ( (fabs(this->EllipsePosition2.s - this->EllipsePosition1.s) > 1E-8) || (fabs(this->EllipsePosition2.t - this->EllipsePosition1.t) > 1E-8) ) { - #ifdef DEBUG_SOLVER - std::cout << "2nd: (s, t)= " << this->EllipsePosition2 << " oePoint()= " << this->oePoint(this->EllipsePosition2) << " e=" << this->error(this->EllipsePosition2) << "\n"; - #endif + if (fabs(this->error(this->EllipsePosition2)) < err1 + OE_ERROR_TOLERANCE) { + if ((fabs(this->EllipsePosition2.s - this->EllipsePosition1.s) > 1E-8) || + (fabs(this->EllipsePosition2.t - this->EllipsePosition1.t) > 1E-8)) { +#ifdef DEBUG_SOLVER + std::cout << "2nd: (s, t)= " << this->EllipsePosition2 + << " oePoint()= " << this->oePoint(this->EllipsePosition2) + << " e=" << this->error(this->EllipsePosition2) << "\n"; +#endif return true; } } - - this->EllipsePosition2.s = -this->EllipsePosition1.s; - this->EllipsePosition2.t = this->EllipsePosition1.t; - if ( fabs(this->error(this->EllipsePosition2)) < err1+OE_ERROR_TOLERANCE) { - if ( (fabs(this->EllipsePosition2.s - this->EllipsePosition1.s) > 1E-8) || (fabs(this->EllipsePosition2.t - this->EllipsePosition1.t) > 1E-8) ) { - #ifdef DEBUG_SOLVER - std::cout << "2nd: (s, t)= " << this->EllipsePosition2 << " oePoint()= " << this->oePoint(this->EllipsePosition2) << " e=" << this->error(this->EllipsePosition2) << "\n"; - #endif + + this->EllipsePosition2.s = -this->EllipsePosition1.s; + this->EllipsePosition2.t = this->EllipsePosition1.t; + if (fabs(this->error(this->EllipsePosition2)) < err1 + OE_ERROR_TOLERANCE) { + if ((fabs(this->EllipsePosition2.s - this->EllipsePosition1.s) > 1E-8) || + (fabs(this->EllipsePosition2.t - this->EllipsePosition1.t) > 1E-8)) { +#ifdef DEBUG_SOLVER + std::cout << "2nd: (s, t)= " << this->EllipsePosition2 + << " oePoint()= " << this->oePoint(this->EllipsePosition2) + << " e=" << this->error(this->EllipsePosition2) << "\n"; +#endif return true; - } + } } - - this->EllipsePosition2.s = -this->EllipsePosition1.s; - this->EllipsePosition2.t = -this->EllipsePosition1.t; - if ( fabs(this->error(this->EllipsePosition2)) < err1+OE_ERROR_TOLERANCE) { - if ( (fabs(this->EllipsePosition2.s - this->EllipsePosition1.s) > 1E-8) || (fabs(this->EllipsePosition2.t - this->EllipsePosition1.t) > 1E-8) ) { - #ifdef DEBUG_SOLVER - std::cout << "2nd: (s, t)= " << this->EllipsePosition2 << " oePoint()= " << this->oePoint(this->EllipsePosition2) << " e=" << this->error(this->EllipsePosition2) << "\n"; - #endif + + this->EllipsePosition2.s = -this->EllipsePosition1.s; + this->EllipsePosition2.t = -this->EllipsePosition1.t; + if (fabs(this->error(this->EllipsePosition2)) < err1 + OE_ERROR_TOLERANCE) { + if ((fabs(this->EllipsePosition2.s - this->EllipsePosition1.s) > 1E-8) || + (fabs(this->EllipsePosition2.t - this->EllipsePosition1.t) > 1E-8)) { +#ifdef DEBUG_SOLVER + std::cout << "2nd: (s, t)= " << this->EllipsePosition2 + << " oePoint()= " << this->oePoint(this->EllipsePosition2) + << " e=" << this->error(this->EllipsePosition2) << "\n"; +#endif return true; } } - + // last desperate attempt is identical solutions - this->EllipsePosition2.s = this->EllipsePosition1.s; - this->EllipsePosition2.t = this->EllipsePosition1.t; - if ( fabs(this->error(this->EllipsePosition2)) < err1+OE_ERROR_TOLERANCE) { + this->EllipsePosition2.s = this->EllipsePosition1.s; + this->EllipsePosition2.t = this->EllipsePosition1.t; + if (fabs(this->error(this->EllipsePosition2)) < err1 + OE_ERROR_TOLERANCE) { // DON'T require solutions to differ - // if ( (fabs(this->EllipsePosition2.s - this->EllipsePosition1.s) > 1E-8) || (fabs(this->EllipsePosition2.t - this->EllipsePosition1.t) > 1E-8) ) { - #ifdef DEBUG_SOLVER - std::cout << "2nd: (s, t)= " << this->EllipsePosition2 << " oePoint()= " << this->oePoint(this->EllipsePosition2) << " e=" << this->error(this->EllipsePosition2) << "\n"; - #endif - //std::cout << " find_EllipsePosition2() desperate-mode\n"; - return true; + // if ( (fabs(this->EllipsePosition2.s - this->EllipsePosition1.s) > 1E-8) || (fabs(this->EllipsePosition2.t - + // this->EllipsePosition1.t) > 1E-8) ) { +#ifdef DEBUG_SOLVER + std::cout << "2nd: (s, t)= " << this->EllipsePosition2 + << " oePoint()= " << this->oePoint(this->EllipsePosition2) + << " e=" << this->error(this->EllipsePosition2) << "\n"; +#endif + // std::cout << " find_EllipsePosition2() desperate-mode\n"; + return true; //} } - std::cout << "Ellipse::find_EllipsePosition2 cannot find EllipsePosition2! \n"; - std::cout << "ellipse= "<< *this << "\n"; + std::cout << "Ellipse::find_EllipsePosition2 cannot find EllipsePosition2! \n"; + std::cout << "ellipse= " << *this << "\n"; print_solutions(); assert(0); // serious error if we get here! - + return false; } @@ -181,57 +180,59 @@ bool Ellipse::find_EllipsePosition2() { // a horrible horrible function... :( /// this is a zero of Ellipse::error() /// returns number of iterations /// -/// called (only?) by BullCutter::singleEdgeDropCanonical() +/// called (only?) by BullCutter::singleEdgeDropCanonical() int Ellipse::solver_brent() { int iters = 1; EllipsePosition apos, bpos; // Brent's method requires bracketing the root in [apos.diangle, bpos.diangle] - apos.setDiangle( 0.0 ); assert( apos.isValid() ); - bpos.setDiangle( 3.0 ); assert( bpos.isValid() ); - if ( fabs( error(apos) ) < OE_ERROR_TOLERANCE ) { // if we are lucky apos is the solution - EllipsePosition1 = apos; // and we do not need to search further. + apos.setDiangle(0.0); + assert(apos.isValid()); + bpos.setDiangle(3.0); + assert(bpos.isValid()); + if (fabs(error(apos)) < OE_ERROR_TOLERANCE) { // if we are lucky apos is the solution + EllipsePosition1 = apos; // and we do not need to search further. find_EllipsePosition2(); return iters; - } else if ( fabs( error(bpos) ) < OE_ERROR_TOLERANCE ) { // or bpos might be the solution? + } else if (fabs(error(bpos)) < OE_ERROR_TOLERANCE) { // or bpos might be the solution? EllipsePosition1 = bpos; - find_EllipsePosition2(); + find_EllipsePosition2(); return iters; } // neither apos nor bpos is the solution // but root is now bracketed, so we can use brent_zero - assert( error(apos) * error(bpos) < 0.0 ); + assert(error(apos) * error(bpos) < 0.0); // this looks for the diangle that makes the offset-ellipse point y-coordinate zero - double dia_sln = brent_zero( apos.diangle, bpos.diangle , 3E-16, OE_ERROR_TOLERANCE, this ); // brent_zero.hpp - EllipsePosition1.setDiangle( dia_sln ); assert( EllipsePosition1.isValid() ); + double dia_sln = brent_zero(apos.diangle, bpos.diangle, 3E-16, OE_ERROR_TOLERANCE, this); // brent_zero.hpp + EllipsePosition1.setDiangle(dia_sln); + assert(EllipsePosition1.isValid()); // because we only work with the y-coordinate of the offset-ellipse-point, there are two symmetric solutions find_EllipsePosition2(); return iters; } - // used by BullCutter pushcutter edge-test -bool AlignedEllipse::aligned_solver( const Fiber& f ) { +bool AlignedEllipse::aligned_solver(const Fiber &f) { error_dir = f.dir.xyPerp(); // now calls to error(diangle) will give the right error - assert( error_dir.xyNorm() > 0.0 ); + assert(error_dir.xyNorm() > 0.0); target = f.p1; // target is either x or y-coord of f.p1 // find position(s) where ellipse tangent is parallel to fiber. Here error() will be minimized/maximized. - // tangent at point is: -a t + b s = -a*major_dir*t + b*minor_dir*s + // tangent at point is: -a t + b s = -a*major_dir*t + b*minor_dir*s // -at ma.y + bs mi.y = 0 for X-fiber // s = sqrt(1-t^2) // -a*ma.y * t + b*mi.y* sqrt(1-t^2) = 0 // => t^2 = b^2 / (a^2 + b^2) double t1(0.0); if (f.p1.y == f.p2.y) - t1 = sqrt( square( b*minor_dir.y ) / ( square( a*major_dir.y ) + square( b*minor_dir.y ) ) ); + t1 = sqrt(square(b * minor_dir.y) / (square(a * major_dir.y) + square(b * minor_dir.y))); else if (f.p1.x == f.p2.x) - t1 = sqrt( square( b*minor_dir.x ) / ( square( a*major_dir.x ) + square( b*minor_dir.x ) ) ); + t1 = sqrt(square(b * minor_dir.x) / (square(a * major_dir.x) + square(b * minor_dir.x))); else assert(0); // bracket root - EllipsePosition tmp,apos,bpos; - double s1 = sqrt(1.0-square(t1)); - bool found_positive=false; - bool found_negative=false; - tmp.setDiangle( xyVectorToDiangle(s1,t1) ); + EllipsePosition tmp, apos, bpos; + double s1 = sqrt(1.0 - square(t1)); + bool found_positive = false; + bool found_negative = false; + tmp.setDiangle(xyVectorToDiangle(s1, t1)); if (error(tmp.diangle) > 0) { found_positive = true; apos = tmp; @@ -239,128 +240,125 @@ bool AlignedEllipse::aligned_solver( const Fiber& f ) { found_negative = true; bpos = tmp; } - tmp.setDiangle( xyVectorToDiangle(s1,-t1) ); + tmp.setDiangle(xyVectorToDiangle(s1, -t1)); if (error(tmp.diangle) > 0) { found_positive = true; apos = tmp; - } - else if (error(tmp.diangle) < 0) { + } else if (error(tmp.diangle) < 0) { found_negative = true; bpos = tmp; - } - tmp.setDiangle( xyVectorToDiangle(-s1,t1) ); + } + tmp.setDiangle(xyVectorToDiangle(-s1, t1)); if (error(tmp.diangle) > 0) { found_positive = true; apos = tmp; - } - else if (error(tmp.diangle) < 0) { + } else if (error(tmp.diangle) < 0) { found_negative = true; bpos = tmp; } - tmp.setDiangle( xyVectorToDiangle(-s1,-t1) ); + tmp.setDiangle(xyVectorToDiangle(-s1, -t1)); if (error(tmp.diangle) > 0) { found_positive = true; apos = tmp; - } - else if (error(tmp.diangle) < 0) { + } else if (error(tmp.diangle) < 0) { found_negative = true; bpos = tmp; } - + if (found_positive) { if (found_negative) { - assert( this->error(apos.diangle) * this->error(bpos.diangle) < 0.0 ); // root is now bracketed. + assert(this->error(apos.diangle) * this->error(bpos.diangle) < 0.0); // root is now bracketed. double lolim(0.0), hilim(0.0); - if (apos.diangle > bpos.diangle ) { + if (apos.diangle > bpos.diangle) { lolim = bpos.diangle; hilim = apos.diangle; } else if (bpos.diangle > apos.diangle) { hilim = bpos.diangle; lolim = apos.diangle; } - double dia_sln = brent_zero( lolim, hilim , 3E-16, OE_ERROR_TOLERANCE, this ); - double dia_sln2 = brent_zero( hilim-4.0, lolim , 3E-16, OE_ERROR_TOLERANCE, this ); - - EllipsePosition1.setDiangle( dia_sln ); - EllipsePosition2.setDiangle( dia_sln2 ); - - assert( EllipsePosition1.isValid() ); - assert( EllipsePosition2.isValid() ); + double dia_sln = brent_zero(lolim, hilim, 3E-16, OE_ERROR_TOLERANCE, this); + double dia_sln2 = brent_zero(hilim - 4.0, lolim, 3E-16, OE_ERROR_TOLERANCE, this); + + EllipsePosition1.setDiangle(dia_sln); + EllipsePosition2.setDiangle(dia_sln2); + + assert(EllipsePosition1.isValid()); + assert(EllipsePosition2.isValid()); /* // FIXME. This assert fails in some cases (30sphere.stl z=0, for example) // FIXME. The allowed error should probably be in proportion to the difficulty of the case. - + if (!isZero_tol( error(EllipsePosition1.diangle) )) { std::cout << "AlignedEllipse::aligned_solver() ERROR \n"; - std::cout << "error(EllipsePosition1.diangle)= "<< error(EllipsePosition1.diangle) << " (expected zero)\n"; - - } + std::cout << "error(EllipsePosition1.diangle)= "<< error(EllipsePosition1.diangle) << " (expected + zero)\n"; + + } assert( isZero_tol( error(EllipsePosition1.diangle) ) ); assert( isZero_tol( error(EllipsePosition2.diangle) ) ); */ - + return true; } } - + return false; } double AlignedEllipse::error(double diangle) const { EllipsePosition tmp; - tmp.setDiangle( diangle ); + tmp.setDiangle(diangle); Point p = this->oePoint(tmp); - Point errorVec = target-p; + Point errorVec = target - p; return errorVec.dot(error_dir); } -double Ellipse::error(double diangle ) const { +double Ellipse::error(double diangle) const { EllipsePosition tmp; - tmp.setDiangle( diangle ); + tmp.setDiangle(diangle); return error(tmp); } -double Ellipse::error(EllipsePosition& pos) const { +double Ellipse::error(EllipsePosition &pos) const { Point p1 = oePoint(pos); return p1.y; } - /// given the two solutions EllipsePosition1 and EllipsePosition2 and the edge up1-up2 /// locate the ellipse center correctly -Point Ellipse::calcEcenter(const Point& up1, const Point& up2, int sln) { - Point cle = ( sln == 1 ? oePoint1() : oePoint2() ); - double xoffset = - cle.x; - // x-coord on line is x = up1.x + t*(up2.x-up1.x) = center.x+offset +Point Ellipse::calcEcenter(const Point &up1, const Point &up2, int sln) { + Point cle = (sln == 1 ? oePoint1() : oePoint2()); + double xoffset = -cle.x; + // x-coord on line is x = up1.x + t*(up2.x-up1.x) = center.x+offset double t = (center.x + xoffset - up1.x) / (up2.x - up1.x); - return up1 + t*(up2-up1); // return a point on the line -} -Point Ellipse::ePointHi() const { - return ePoint( EllipsePosition_hi ); + return up1 + t * (up2 - up1); // return a point on the line } +Point Ellipse::ePointHi() const { return ePoint(EllipsePosition_hi); } -void Ellipse::setEllipsePositionHi(const Point& u1, const Point& u2) { - Point ecen1 = calcEcenter( u1, u2, 1); - Point ecen2 = calcEcenter( u1, u2, 2); +void Ellipse::setEllipsePositionHi(const Point &u1, const Point &u2) { + Point ecen1 = calcEcenter(u1, u2, 1); + Point ecen2 = calcEcenter(u1, u2, 2); if (ecen1.z >= ecen2.z) { // we want the higher center EllipsePosition_hi = EllipsePosition1; center = ecen1; } else { EllipsePosition_hi = EllipsePosition2; center = ecen2; - } + } } void Ellipse::print_solutions() { - std::cout << "1st: (s, t)= " << EllipsePosition1 << " oePoint()= " << oePoint(EllipsePosition1) << " e=" << error(EllipsePosition1) << "\n"; - std::cout << "2nd: (s, t)= " << EllipsePosition2 << " oePoint()= " << oePoint(EllipsePosition2) << " e=" << error(EllipsePosition2) << "\n"; + std::cout << "1st: (s, t)= " << EllipsePosition1 << " oePoint()= " << oePoint(EllipsePosition1) + << " e=" << error(EllipsePosition1) << "\n"; + std::cout << "2nd: (s, t)= " << EllipsePosition2 << " oePoint()= " << oePoint(EllipsePosition2) + << " e=" << error(EllipsePosition2) << "\n"; } /// Ellipse string output -std::ostream& operator<<(std::ostream &stream, const Ellipse& e) { - stream << "Ellipse: cen=" << e.center << " a=" << e.a << " b=" << e.b << " ofs=" << e.offset ; - return stream; +std::ostream &operator<<(std::ostream &stream, const Ellipse &e) { + stream << "Ellipse: cen=" << e.center << " a=" << e.a << " b=" << e.b << " ofs=" << e.offset; + return stream; } -} // end namespace +} // namespace ocl // end of file oellipse.cpp diff --git a/src/cutters/ellipse.hpp b/src/cutters/ellipse.hpp index e177b750..20029df4 100644 --- a/src/cutters/ellipse.hpp +++ b/src/cutters/ellipse.hpp @@ -1,143 +1,142 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef ELLIPSE_H #define ELLIPSE_H #include -#include "point.hpp" #include "ellipseposition.hpp" +#include "point.hpp" -namespace ocl -{ +namespace ocl { class Fiber; -/// An Ellipse. +/// An Ellipse. class Ellipse { - public: - /// dummy constructor - Ellipse(){} - /// create an Ellipse with centerpoint center, X-axis a, Y-axis b, and offset distance offset. - Ellipse(Point& centerin, double a, double b, double offset); - - /// return a point on the ellipse at given EllipsePosition - virtual Point ePoint(const EllipsePosition& position) const; - /// return a point on the offset-ellipse at given EllipsePosition - virtual Point oePoint(const EllipsePosition& position) const; - /// return a normalized normal vector of the ellipse at the given EllipsePosition - virtual Point normal(const EllipsePosition& position) const; + public: + /// dummy constructor + Ellipse() {} + /// create an Ellipse with centerpoint center, X-axis a, Y-axis b, and offset distance offset. + Ellipse(Point ¢erin, double a, double b, double offset); + + /// return a point on the ellipse at given EllipsePosition + virtual Point ePoint(const EllipsePosition &position) const; + /// return a point on the offset-ellipse at given EllipsePosition + virtual Point oePoint(const EllipsePosition &position) const; + /// return a normalized normal vector of the ellipse at the given EllipsePosition + virtual Point normal(const EllipsePosition &position) const; + + /// offset-ellipse Brent solver + int solver_brent(); + /// print out the found solutions + void print_solutions(); + /// given one EllipsePosition solution, find the other. + bool find_EllipsePosition2(); + /// error function for the solver + double error(EllipsePosition &position) const; + /// error function for solver + virtual double error(double dia) const; + /// calculate ellipse center + Point calcEcenter(const Point &up1, const Point &up2, int sln); + /// set EllipsePosition_hi to either EllipsePosition1 or EllipsePosition2, depending on which + /// has the center (given by calcEcenter() ) with higher z-coordinate + void setEllipsePositionHi(const Point &u1, const Point &u2); + /// once EllipsePosition_hi is set, return an ellipse-point at this position + Point ePointHi() const; + /// ellipse-point at EllipsePosition1 + Point ePoint1() const; + /// ellipse-point at EllipsePosition2 + Point ePoint2() const; + /// offset-ellipse-point at EllipsePosition1 + Point oePoint1() const; + /// offset-ellipse-point at EllipsePosition2 + Point oePoint2() const; - /// offset-ellipse Brent solver - int solver_brent(); - /// print out the found solutions - void print_solutions(); - /// given one EllipsePosition solution, find the other. - bool find_EllipsePosition2(); - /// error function for the solver - double error(EllipsePosition& position) const; - /// error function for solver - virtual double error(double dia) const; - /// calculate ellipse center - Point calcEcenter(const Point& up1, const Point& up2, int sln); - /// set EllipsePosition_hi to either EllipsePosition1 or EllipsePosition2, depending on which - /// has the center (given by calcEcenter() ) with higher z-coordinate - void setEllipsePositionHi(const Point& u1, const Point& u2); - /// once EllipsePosition_hi is set, return an ellipse-point at this position - Point ePointHi() const; - /// ellipse-point at EllipsePosition1 - Point ePoint1() const; - /// ellipse-point at EllipsePosition2 - Point ePoint2() const; - /// offset-ellipse-point at EllipsePosition1 - Point oePoint1() const; - /// offset-ellipse-point at EllipsePosition2 - Point oePoint2() const; + /// string repr + friend std::ostream &operator<<(std::ostream &stream, const Ellipse &e); + /// set length of ellipse major axis + void setA(double ain) { a = ain; } + /// set length of ellipse minor axis + void setB(double bin) { b = bin; } + /// set the ellipse center + void setCenter(Point &pin) { center = pin; } + /// set offset-ellipse offset distance + void setOffset(double ofs) { offset = ofs; } + /// set/calculate the eccentricity + void setEccen() { eccen = a / b; } + /// returns the z-coordinate of this->center + inline double getCenterZ() { return center.z; } - - /// string repr - friend std::ostream &operator<<(std::ostream &stream, const Ellipse& e); - /// set length of ellipse major axis - void setA(double ain) {a=ain;} - /// set length of ellipse minor axis - void setB(double bin) {b=bin;} - /// set the ellipse center - void setCenter(Point& pin) {center=pin;} - /// set offset-ellipse offset distance - void setOffset(double ofs) {offset=ofs;} - /// set/calculate the eccentricity - void setEccen() {eccen=a/b;} - /// returns the z-coordinate of this->center - inline double getCenterZ() {return center.z;} - - /// eccentricity = a/b - double eccen; - - protected: - /// first EllipsePosition solution found by solver() - EllipsePosition EllipsePosition1; - /// second EllipsePosition solution found by solver() - EllipsePosition EllipsePosition2; - /// the higher EllipsePosition solution - EllipsePosition EllipsePosition_hi; - - /// the center point of the ellipse - Point center; - /// a-axis, in the X-direction - double a; - /// b-axis, in the Y-direction - double b; - /// offset - double offset; - /// the target Point for the error-function - Point target; + /// eccentricity = a/b + double eccen; + + protected: + /// first EllipsePosition solution found by solver() + EllipsePosition EllipsePosition1; + /// second EllipsePosition solution found by solver() + EllipsePosition EllipsePosition2; + /// the higher EllipsePosition solution + EllipsePosition EllipsePosition_hi; + + /// the center point of the ellipse + Point center; + /// a-axis, in the X-direction + double a; + /// b-axis, in the Y-direction + double b; + /// offset + double offset; + /// the target Point for the error-function + Point target; }; /// an aligned ellipse, used by the edgePush function of BullCutter class AlignedEllipse : public Ellipse { - public: - AlignedEllipse(){} - /// create an aligned ellipse - AlignedEllipse(Point& centerin, double major_length, double minor_length, - double offset, Point& majorDir, Point& minorDir); - /// normal vector at given EllipsePosition - Point normal(const EllipsePosition& position) const; - /// ellipse-point at given EllipsePosition - Point ePoint(const EllipsePosition& position) const; - /// offset-ellipse point at given EllipsePosition - Point oePoint(const EllipsePosition& pos) const; - /// error-function for the solver - double error(double dia) const; - /// aligned offset-ellipse solver. callsn Numeric::brent_solver() - bool aligned_solver( const Fiber& f ); - private: - /// direction of the major axis - Point major_dir; - /// direction of the minor axis - Point minor_dir; - /// the error-direction for error() - Point error_dir; + public: + AlignedEllipse() {} + /// create an aligned ellipse + AlignedEllipse(Point ¢erin, double major_length, double minor_length, double offset, Point &majorDir, + Point &minorDir); + /// normal vector at given EllipsePosition + Point normal(const EllipsePosition &position) const; + /// ellipse-point at given EllipsePosition + Point ePoint(const EllipsePosition &position) const; + /// offset-ellipse point at given EllipsePosition + Point oePoint(const EllipsePosition &pos) const; + /// error-function for the solver + double error(double dia) const; + /// aligned offset-ellipse solver. callsn Numeric::brent_solver() + bool aligned_solver(const Fiber &f); + + private: + /// direction of the major axis + Point major_dir; + /// direction of the minor axis + Point minor_dir; + /// the error-direction for error() + Point error_dir; }; -} // end namespace +} // namespace ocl #endif // end file ellipse.h diff --git a/src/cutters/ellipseposition.cpp b/src/cutters/ellipseposition.cpp index b703d68b..bd10d444 100644 --- a/src/cutters/ellipseposition.cpp +++ b/src/cutters/ellipseposition.cpp @@ -1,36 +1,35 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ -#include #include +#include // uncomment to disable assert() calls // #define NDEBUG #include -#include "point.hpp" -#include "ellipseposition.hpp" #include "ellipse.hpp" +#include "ellipseposition.hpp" #include "numeric.hpp" -namespace ocl -{ +#include "point.hpp" +namespace ocl { //******** EllipsePosition ********************** */ EllipsePosition::EllipsePosition() { @@ -52,26 +51,25 @@ void EllipsePosition::setD() { // (a < 3 ? ((a > 1) ? 2-a : a) : a-4) double d = diangle; assert(!boost::math::isnan(d)); - while ( d > 4.0 ) // make d a diangle in [0,4] + while (d > 4.0) // make d a diangle in [0,4] d -= 4.0; - while ( d < 0.0) - d+=4.0; - - assert( d >= 0.0 && d <= 4.0 ); // now we should be in [0,4] - Point p( (d < 2 ? 1-d : d-3) , - (d < 3 ? ((d > 1) ? 2-d : d) : d-4) ); + while (d < 0.0) + d += 4.0; + + assert(d >= 0.0 && d <= 4.0); // now we should be in [0,4] + Point p((d < 2 ? 1 - d : d - 3), (d < 3 ? ((d > 1) ? 2 - d : d) : d - 4)); // now we have a vector pointing in the right direction // but it is not normalized p.normalize(); s = p.x; t = p.y; - assert( this->isValid() ); + assert(this->isValid()); } // check that s and t values are OK bool EllipsePosition::isValid() const { - if ( isZero_tol( square(s) + square(t) - 1.0 ) ) + if (isZero_tol(square(s) + square(t) - 1.0)) return true; else { std::cout << " EllipsePosition=" << *this << "\n"; @@ -80,7 +78,7 @@ bool EllipsePosition::isValid() const { } } -EllipsePosition& EllipsePosition::operator=(const EllipsePosition &pos) { +EllipsePosition &EllipsePosition::operator=(const EllipsePosition &pos) { s = pos.s; t = pos.t; diangle = pos.diangle; @@ -93,10 +91,10 @@ std::string EllipsePosition::str() const { return o.str(); } -std::ostream& operator<<(std::ostream &stream, EllipsePosition pos) { - stream << "("<< pos.s <<" ," << pos.t << ")"; +std::ostream &operator<<(std::ostream &stream, EllipsePosition pos) { + stream << "(" << pos.s << " ," << pos.t << ")"; return stream; } -}//end namespace -//end file ellipseposition.cpp +} // namespace ocl +// end file ellipseposition.cpp diff --git a/src/cutters/ellipseposition.hpp b/src/cutters/ellipseposition.hpp index bdc14af3..60e6afcf 100644 --- a/src/cutters/ellipseposition.hpp +++ b/src/cutters/ellipseposition.hpp @@ -1,23 +1,23 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef ELLIPSEPOSITION_H #define ELLIPSEPOSITION_H @@ -26,49 +26,51 @@ #include "point.hpp" -namespace ocl -{ - +namespace ocl { + class Ellipse; /// /// \brief EllipsePosition defines a position in (s,t) coordinates on a unit-circle. /// The (s,t) pair is used to locate points on an ellipse. -/// +/// /// s^2 + t^2 = 1 should be true at all times. class EllipsePosition { - public: - /// create an EllipsePosition - EllipsePosition(); - /// create EllipsePosition at (s,t) - EllipsePosition(double sin, double tin){s=sin; t=tin;} - /// set (s,t) pair to the position corresponding to diangle - void setDiangle(double dia); - /// set rhs EllipsePosition (s,t) values equal to lhs EllipsePosition - EllipsePosition &operator=(const EllipsePosition &pos); - /// return true if (s,t) is valid, i.e. lies on the unit circle - /// checks s^2 + t^2 == 1 (to within tolerance) - bool isValid() const; - - /// string repr - std::string str() const; - /// string repr - friend std::ostream& operator<<(std::ostream &stream, EllipsePosition pos); - + public: + /// create an EllipsePosition + EllipsePosition(); + /// create EllipsePosition at (s,t) + EllipsePosition(double sin, double tin) { + s = sin; + t = tin; + } + /// set (s,t) pair to the position corresponding to diangle + void setDiangle(double dia); + /// set rhs EllipsePosition (s,t) values equal to lhs EllipsePosition + EllipsePosition &operator=(const EllipsePosition &pos); + /// return true if (s,t) is valid, i.e. lies on the unit circle + /// checks s^2 + t^2 == 1 (to within tolerance) + bool isValid() const; + + /// string repr + std::string str() const; + /// string repr + friend std::ostream &operator<<(std::ostream &stream, EllipsePosition pos); + // DATA - /// s-parameter in [-1, 1] - double s; - /// t-parameter in [-1, 1] - double t; - /// diamond angle parameter in [0,4] (modulo 4) - /// this models an angle [0,2pi] and maps - /// from the angle to an (s,t) pair using setD() - double diangle; - - private: - /// set (s,t) pair to match diangle - void setD(); + /// s-parameter in [-1, 1] + double s; + /// t-parameter in [-1, 1] + double t; + /// diamond angle parameter in [0,4] (modulo 4) + /// this models an angle [0,2pi] and maps + /// from the angle to an (s,t) pair using setD() + double diangle; + + private: + /// set (s,t) pair to match diangle + void setD(); }; - -}// end namespace + +} // namespace ocl #endif // end file EllipsePosition.h diff --git a/src/cutters/millingcutter.cpp b/src/cutters/millingcutter.cpp index ab702596..24d01336 100644 --- a/src/cutters/millingcutter.cpp +++ b/src/cutters/millingcutter.cpp @@ -1,116 +1,116 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #include #include "millingcutter.hpp" #include "numeric.hpp" -namespace ocl -{ +namespace ocl { -MillingCutter* MillingCutter::offsetCutter(double d) const { +MillingCutter *MillingCutter::offsetCutter(double d) const { assert(0); // DON'T call me - return NULL; + return NULL; } -// general purpose vertex-drop which delegates to this->height(r) of subclass +// general purpose vertex-drop which delegates to this->height(r) of subclass bool MillingCutter::vertexDrop(CLPoint &cl, const Triangle &t) const { bool result = false; - BOOST_FOREACH( const Point& p, t.p) { // test each vertex of triangle - double q = cl.xyDistance(p); // distance in XY-plane from cl to p - if ( q <= radius ) { // p is inside the cutter + BOOST_FOREACH (const Point &p, t.p) { // test each vertex of triangle + double q = cl.xyDistance(p); // distance in XY-plane from cl to p + if (q <= radius) { // p is inside the cutter CCPoint cc_tmp(p, VERTEX); - if ( cl.liftZ( p.z - this->height(q), cc_tmp ) ) + if (cl.liftZ(p.z - this->height(q), cc_tmp)) result = true; - } + } } return result; } -// general purpose facet-drop which calls xy_normal_length(), normal_length(), +// general purpose facet-drop which calls xy_normal_length(), normal_length(), // and center_height() on the subclass -bool MillingCutter::facetDrop(CLPoint &cl, const Triangle &t) const { // Drop cutter at (cl.x, cl.y) against facet of Triangle t - Point normal = t.upNormal(); // facet surface normal - if ( isZero_tol( normal.z ) ) // vertical surface - return false; //can't drop against vertical surface - assert( isPositive( normal.z ) ); - - if ( ( isZero_tol(normal.x) ) && ( isZero_tol(normal.y) ) ) { // horizontal plane special case - CCPoint cc_tmp( cl.x, cl.y, t.p[0].z, FACET); +bool MillingCutter::facetDrop(CLPoint &cl, + const Triangle &t) const { // Drop cutter at (cl.x, cl.y) against facet of Triangle t + Point normal = t.upNormal(); // facet surface normal + if (isZero_tol(normal.z)) // vertical surface + return false; // can't drop against vertical surface + assert(isPositive(normal.z)); + + if ((isZero_tol(normal.x)) && (isZero_tol(normal.y))) { // horizontal plane special case + CCPoint cc_tmp(cl.x, cl.y, t.p[0].z, FACET); return cl.liftZ_if_inFacet(cc_tmp.z, cc_tmp, t); } else { // general case // plane containing facet: a*x + b*y + c*z + d = 0, so // d = -a*x - b*y - c*z, where (a,b,c) = surface normal - double d = - normal.dot(t.p[0]); + double d = -normal.dot(t.p[0]); normal.normalize(); // make length of normal == 1.0 - Point xyNormal( normal.x, normal.y, 0.0); + Point xyNormal(normal.x, normal.y, 0.0); xyNormal.xyNormalize(); - // define the radiusvector which points from the cc-point to the cutter-center - Point radiusvector = this->xy_normal_length*xyNormal + this->normal_length*normal; + // define the radiusvector which points from the cc-point to the cutter-center + Point radiusvector = this->xy_normal_length * xyNormal + this->normal_length * normal; CCPoint cc_tmp = cl - radiusvector; // NOTE xy-coords right, z-coord is not. - cc_tmp.z = (1.0/normal.z)*(-d-normal.x*cc_tmp.x-normal.y*cc_tmp.y); // cc-point lies in the plane. + cc_tmp.z = (1.0 / normal.z) * (-d - normal.x * cc_tmp.x - normal.y * cc_tmp.y); // cc-point lies in the plane. cc_tmp.type = FACET; double tip_z = cc_tmp.z + radiusvector.z - this->center_height; return cl.liftZ_if_inFacet(tip_z, cc_tmp, t); } } -// edge-drop function which calls the sub-class MillingCutter::singleEdgeDrop on each +// edge-drop function which calls the sub-class MillingCutter::singleEdgeDrop on each // edge of the input Triangle t. bool MillingCutter::edgeDrop(CLPoint &cl, const Triangle &t) const { bool result = false; - for (int n=0;n<3;n++) { // loop through all three edges - int start=n; // index of the start-point of the edge - int end=(n+1)%3; // index of the end-point of the edge + for (int n = 0; n < 3; n++) { // loop through all three edges + int start = n; // index of the start-point of the edge + int end = (n + 1) % 3; // index of the end-point of the edge const Point p1 = t.p[start]; const Point p2 = t.p[end]; - if ( !isZero_tol( p1.x - p2.x) || !isZero_tol( p1.y - p2.y) ) { - const double d = cl.xyDistanceToLine(p1,p2); - if (d<=radius) // potential contact with edge - if ( this->singleEdgeDrop(cl,p1,p2,d) ) - result=true; + if (!isZero_tol(p1.x - p2.x) || !isZero_tol(p1.y - p2.y)) { + const double d = cl.xyDistanceToLine(p1, p2); + if (d <= radius) // potential contact with edge + if (this->singleEdgeDrop(cl, p1, p2, d)) + result = true; } } return result; } -// 1) translate the geometry so that in the XY plane cl = (0,0) +// 1) translate the geometry so that in the XY plane cl = (0,0) // 2) rotate the p1-p2 edge so that a new edge u1-u2 lies along the x-axis // 3) call singleEdgeDropCanonical(), implemented in the sub-class. // this returns the x-coordinate of the CC point and cl.z // 4) rotate/translate back to the original geometry -// 5) update cl.z if required and if CC lies within the edge +// 5) update cl.z if required and if CC lies within the edge // // The edge test can be done in a "dual" geometry. -// instead of testing the original cutter against an infinitely thin edge +// instead of testing the original cutter against an infinitely thin edge // we can test a virtual CylCutter with radius VR against an infinite ER-radius cylinder around the edge. // This reduces to a 2D problem in the XY plane, where section of the ER-radius cylinder is an ellipse. // in the general case CL lies on an offset ellipse with offset OR. // The general cases only applies for BullCutter(R1,R2) where R1 is the shaft radius -// and R2 is the corner radius. +// and R2 is the corner radius. // For CylCutter and BallCutter there are simple analytic solutions and an offset ellipse approach is not required. // // The dual problem for each cutter type is: -// +// // CylCutter(R): VR = R, ER = 0, OR=R (the z-position of VR is the same as for CylCutter) // BallCutter(R): VR = 0, ER = R, OR=0 (the z-position of VR is a distance R up from the tip of BallCutter) // BullCutter(R1,R2): VR=R1-R2, ER=R2, OR=R1-R2 (z-position of VR is a distance R2 up from the tip of BullCutter) @@ -118,82 +118,74 @@ bool MillingCutter::edgeDrop(CLPoint &cl, const Triangle &t) const { // cone: ??? (how is this an ellipse??) // // d is the distance from the p1-p2 line to cl, in the 2D XY plane -bool MillingCutter::singleEdgeDrop(CLPoint& cl, const Point& p1, const Point& p2, double d) const { - Point v = p2 - p1; // vector along edge, from p1 -> p2 - Point vxy( v.x, v.y, 0.0); // XY projection - vxy.xyNormalize(); // normalized XY edge vector +bool MillingCutter::singleEdgeDrop(CLPoint &cl, const Point &p1, const Point &p2, double d) const { + Point v = p2 - p1; // vector along edge, from p1 -> p2 + Point vxy(v.x, v.y, 0.0); // XY projection + vxy.xyNormalize(); // normalized XY edge vector // figure out u-coordinates of p1 and p2 (i.e. x-coord in the rotated system) - Point sc = cl.xyClosestPoint( p1, p2 ); - assert( ( (cl-sc).xyNorm() - d ) < 1E-6 ); + Point sc = cl.xyClosestPoint(p1, p2); + assert(((cl - sc).xyNorm() - d) < 1E-6); // edge endpoints in the new coordinate system, in these coordinates, CL is at origo - Point u1( (p1-sc).dot(vxy) , d, p1.z); // d, the distance to line, is the y-coord in the rotated system - Point u2( (p2-sc).dot(vxy) , d, p2.z); - CC_CLZ_Pair contact = this->singleEdgeDropCanonical( u1, u2 ); // the subclass handles this - CCPoint cc_tmp( sc + contact.first * vxy, EDGE); // translate back into original coord-system - cc_tmp.z_projectOntoEdge(p1,p2); + Point u1((p1 - sc).dot(vxy), d, p1.z); // d, the distance to line, is the y-coord in the rotated system + Point u2((p2 - sc).dot(vxy), d, p2.z); + CC_CLZ_Pair contact = this->singleEdgeDropCanonical(u1, u2); // the subclass handles this + CCPoint cc_tmp(sc + contact.first * vxy, EDGE); // translate back into original coord-system + cc_tmp.z_projectOntoEdge(p1, p2); // update cl.z if required, and the cc-point lies inside the p1-p2 edge. - return cl.liftZ_if_InsidePoints( contact.second , cc_tmp , p1, p2); + return cl.liftZ_if_InsidePoints(contact.second, cc_tmp, p1, p2); } -// general purpose vertexPush, delegates to this->width(h) -bool MillingCutter::vertexPush(const Fiber& f, Interval& i, const Triangle& t) const { +// general purpose vertexPush, delegates to this->width(h) +bool MillingCutter::vertexPush(const Fiber &f, Interval &i, const Triangle &t) const { bool result = false; - BOOST_FOREACH( const Point& p, t.p) { - if (this->singleVertexPush(f,i,p, VERTEX) ) + BOOST_FOREACH (const Point &p, t.p) { + if (this->singleVertexPush(f, i, p, VERTEX)) result = true; } return result; } -bool MillingCutter::singleVertexPush(const Fiber& f, Interval& i, const Point& p, CCType cctyp) const { +bool MillingCutter::singleVertexPush(const Fiber &f, Interval &i, const Point &p, CCType cctyp) const { bool result = false; - if ( ( p.z >= f.p1.z ) && ( p.z <= (f.p1.z+ this->getLength()) ) ) { // p.z is within cutter - Point pq = p.xyClosestPoint(f.p1, f.p2); // closest point on fiber - double q = (p-pq).xyNorm(); // distance in XY-plane from fiber to p + if ((p.z >= f.p1.z) && (p.z <= (f.p1.z + this->getLength()))) { // p.z is within cutter + Point pq = p.xyClosestPoint(f.p1, f.p2); // closest point on fiber + double q = (p - pq).xyNorm(); // distance in XY-plane from fiber to p double h = p.z - f.p1.z; - assert( h>= 0.0); - double cwidth = this->width( h ); - if ( q <= cwidth ) { // we are going to hit the vertex p - double ofs = sqrt( square( cwidth ) - square(q) ); // distance along fiber - Point start = pq - ofs*f.dir; - Point stop = pq + ofs*f.dir; - CCPoint cc_tmp( p, cctyp ); - i.updateUpper( f.tval(stop) , cc_tmp ); - i.updateLower( f.tval(start) , cc_tmp ); - result = true; - } + assert(h >= 0.0); + double cwidth = this->width(h); + if (q <= cwidth) { // we are going to hit the vertex p + double ofs = sqrt(square(cwidth) - square(q)); // distance along fiber + Point start = pq - ofs * f.dir; + Point stop = pq + ofs * f.dir; + CCPoint cc_tmp(p, cctyp); + i.updateUpper(f.tval(stop), cc_tmp); + i.updateLower(f.tval(start), cc_tmp); + result = true; + } } return result; } -bool MillingCutter::facetPush(const Fiber& fib, Interval& i, const Triangle& t) const { - return generalFacetPush(this->normal_length, - this->center_height, - this->xy_normal_length, - fib,i,t); +bool MillingCutter::facetPush(const Fiber &fib, Interval &i, const Triangle &t) const { + return generalFacetPush(this->normal_length, this->center_height, this->xy_normal_length, fib, i, t); } - + // general purpose facetPush -bool MillingCutter::generalFacetPush(double normal_length, - double center_height, - double xy_normal_length, - const Fiber& fib, - Interval& i, - const Triangle& t) - const { +bool MillingCutter::generalFacetPush(double normal_length, double center_height, double xy_normal_length, + const Fiber &fib, Interval &i, const Triangle &t) const { bool result = false; - Point normal = t.upNormal(); // facet surface normal, pointing up - if ( normal.zParallel() ) // normal points in z-dir - return result; //can't push against horizontal plane, stop here. + Point normal = t.upNormal(); // facet surface normal, pointing up + if (normal.zParallel()) // normal points in z-dir + return result; // can't push against horizontal plane, stop here. normal.normalize(); Point xy_normal = normal; xy_normal.z = 0; xy_normal.xyNormalize(); - - // find a point on the plane from which radius2*normal+radius1*xy_normal lands on the fiber+radius2*Point(0,0,1) + + // find a point on the plane from which radius2*normal+radius1*xy_normal lands on the fiber+radius2*Point(0,0,1) // (u,v) locates a point on the triangle facet v0+ u*(v1-v0)+v*(v2-v0) u,v in [0,1] // t locates a point along the fiber: p1 + t*(p2-p1) t in [0,1] - // + // // facet-point + r2 * n + r1* xy_n = fiber-point + r2*Point(0,0,1) // => // v0+ u*(v1-v0)+v*(v2-v0) + r2 * n + r1* xy_n = p1 + t*(p2-p1) + r2*Point(0,0,1) @@ -202,7 +194,7 @@ bool MillingCutter::generalFacetPush(double normal_length, // v0y + u*(v1y-v0y) + v*(v2y-v0y) + r2*ny + r1*xy_n.y = p1y + t*(p2y-p1y) p2y-p1y==0 for X-fiber // v0z + u*(v1z-v0z) + v*(v2z-v0z) + r2*nz = p1z + t*(p2z-p1z) + r2 (p2z-p1z)==0 for XY-fibers!! // X-fiber: - // v0x + u*(v1x-v0x) + v*(v2x-v0x) + r2*nx + r1*xy_n.x = p1x + t*(p2x-p1x) + // v0x + u*(v1x-v0x) + v*(v2x-v0x) + r2*nx + r1*xy_n.x = p1x + t*(p2x-p1x) // v0y + u*(v1y-v0y) + v*(v2y-v0y) + r2*ny + r1*xy_n.y = p1y solve these two for (u,v) // v0z + u*(v1z-v0z) + v*(v2z-v0z) + r2*nz = p1z + r2 and substitute above for t // or @@ -211,227 +203,227 @@ bool MillingCutter::generalFacetPush(double normal_length, // // Y-fiber: // [ (v1x-v0x) (v2x-v0x) ] [ u ] = [ -v0x - r2*nx - r1*xy_n.x + p1x ] - + double a; double b; double c = t.p[1].z - t.p[0].z; double d = t.p[2].z - t.p[0].z; double e; - double f = -t.p[0].z - normal_length*normal.z + fib.p1.z + center_height; + double f = -t.p[0].z - normal_length * normal.z + fib.p1.z + center_height; // note: the xy_normal does not have a z-component, so omitted here. - + double u, v; // u and v are coordinates of the cc-point within the triangle facet // a,b,e depend on the fiber: - if ( fib.p1.y == fib.p2.y ) { // XFIBER + if (fib.p1.y == fib.p2.y) { // XFIBER a = t.p[1].y - t.p[0].y; b = t.p[2].y - t.p[0].y; - e = -t.p[0].y - normal_length*normal.y - xy_normal_length*xy_normal.y + fib.p1.y; - if (!two_by_two_solver(a,b,c,d,e,f,u,v)) + e = -t.p[0].y - normal_length * normal.y - xy_normal_length * xy_normal.y + fib.p1.y; + if (!two_by_two_solver(a, b, c, d, e, f, u, v)) return result; - CCPoint cc = t.p[0] + u*(t.p[1]-t.p[0]) + v*(t.p[2]-t.p[0]); + CCPoint cc = t.p[0] + u * (t.p[1] - t.p[0]) + v * (t.p[2] - t.p[0]); cc.type = FACET; - if ( ! cc.isInside( t ) ) + if (!cc.isInside(t)) return result; - // v0x + u*(v1x-v0x) + v*(v2x-v0x) + r2*nx + r1*xy_n.x = p1x + t*(p2x-p1x) + // v0x + u*(v1x-v0x) + v*(v2x-v0x) + r2*nx + r1*xy_n.x = p1x + t*(p2x-p1x) // => // t = 1/(p2x-p1x) * ( v0x + r2*nx + r1*xy_n.x - p1x + u*(v1x-v0x) + v*(v2x-v0x) ) - assert( !isZero_tol( fib.p2.x - fib.p1.x ) ); // guard against division by zero - double tval = (1.0/( fib.p2.x - fib.p1.x )) * ( t.p[0].x + normal_length*normal.x + xy_normal_length*xy_normal.x - fib.p1.x - + u*(t.p[1].x-t.p[0].x)+v*(t.p[2].x-t.p[0].x) ); - if ( tval < 0.0 || tval > 1.0 ) { + assert(!isZero_tol(fib.p2.x - fib.p1.x)); // guard against division by zero + double tval = + (1.0 / (fib.p2.x - fib.p1.x)) * (t.p[0].x + normal_length * normal.x + xy_normal_length * xy_normal.x - + fib.p1.x + u * (t.p[1].x - t.p[0].x) + v * (t.p[2].x - t.p[0].x)); + if (tval < 0.0 || tval > 1.0) { std::cout << "MillingCutter::facetPush() tval= " << tval << " error!?\n"; - //std::cout << " cutter: " << *this << "\n"; + // std::cout << " cutter: " << *this << "\n"; std::cout << " triangle: " << t << "\n"; std::cout << " fiber: " << fib << "\n"; - } - assert( tval > 0.0 && tval < 1.0 ); - i.update( tval, cc ); + } + assert(tval > 0.0 && tval < 1.0); + i.update(tval, cc); result = true; } else if (fib.p1.x == fib.p2.x) { // YFIBER a = t.p[1].x - t.p[0].x; b = t.p[2].x - t.p[0].x; - e = -t.p[0].x - normal_length*normal.x - xy_normal_length*xy_normal.x + fib.p1.x; - if (!two_by_two_solver(a,b,c,d,e,f,u,v)) + e = -t.p[0].x - normal_length * normal.x - xy_normal_length * xy_normal.x + fib.p1.x; + if (!two_by_two_solver(a, b, c, d, e, f, u, v)) return result; - CCPoint cc = t.p[0] + u*(t.p[1]-t.p[0]) + v*(t.p[2]-t.p[0]); + CCPoint cc = t.p[0] + u * (t.p[1] - t.p[0]) + v * (t.p[2] - t.p[0]); cc.type = FACET; - if ( ! cc.isInside( t ) ) + if (!cc.isInside(t)) return result; - assert( !isZero_tol( fib.p2.y - fib.p1.y ) ); - double tval = (1.0/( fib.p2.y - fib.p1.y )) * ( t.p[0].y + normal_length*normal.y + xy_normal_length*xy_normal.y - fib.p1.y - + u*(t.p[1].y-t.p[0].y)+v*(t.p[2].y-t.p[0].y) ); - if ( tval < 0.0 || tval > 1.0 ) { + assert(!isZero_tol(fib.p2.y - fib.p1.y)); + double tval = + (1.0 / (fib.p2.y - fib.p1.y)) * (t.p[0].y + normal_length * normal.y + xy_normal_length * xy_normal.y - + fib.p1.y + u * (t.p[1].y - t.p[0].y) + v * (t.p[2].y - t.p[0].y)); + if (tval < 0.0 || tval > 1.0) { std::cout << "MillingCutter::facetPush() tval= " << tval << " error!?\n"; std::cout << " (most probably a user error, the fiber is too short compared to the STL model?)\n"; - } - assert( tval > 0.0 && tval < 1.0 ); - i.update( tval, cc ); - result = true; + } + assert(tval > 0.0 && tval < 1.0); + i.update(tval, cc); + result = true; } else { assert(0); } - + return result; } -bool MillingCutter::edgePush(const Fiber& f, Interval& i, const Triangle& t) const { +bool MillingCutter::edgePush(const Fiber &f, Interval &i, const Triangle &t) const { bool result = false; - for (int n=0;n<3;n++) { // loop through all three edges - int start=n; - int end=(n+1)%3; + for (int n = 0; n < 3; n++) { // loop through all three edges + int start = n; + int end = (n + 1) % 3; const Point p1 = t.p[start]; // edge is from p1 to p2 const Point p2 = t.p[end]; - if ( this->singleEdgePush(f,i,p1,p2)) + if (this->singleEdgePush(f, i, p1, p2)) result = true; - } + } return result; } -bool MillingCutter::singleEdgePush(const Fiber& f, Interval& i, const Point& p1, const Point& p2) const { +bool MillingCutter::singleEdgePush(const Fiber &f, Interval &i, const Point &p1, const Point &p2) const { bool result = false; - if ( this->horizEdgePush(f,i,p1,p2) ) + if (this->horizEdgePush(f, i, p1, p2)) result = true; else { - if ( this->shaftEdgePush(f,i,p1,p2) ) + if (this->shaftEdgePush(f, i, p1, p2)) result = true; - if ( this->generalEdgePush(f,i,p1,p2) ) + if (this->generalEdgePush(f, i, p1, p2)) result = true; } return result; } // this is used for the cylindrical shaft of Cyl, Ball, Bull, Cone -bool MillingCutter::shaftEdgePush(const Fiber& f, Interval& i, const Point& p1, const Point& p2) const { +bool MillingCutter::shaftEdgePush(const Fiber &f, Interval &i, const Point &p1, const Point &p2) const { // push cutter along Fiber f in contact with edge p1-p2 // contact with cylindrical cutter shaft - double u,v; + double u, v; bool result = false; - if ( xy_line_line_intersection(p1, p2, u, f.p1, f.p2, v ) ) { // find XY-intersection btw fiber and edge - Point q = p1 + u*(p2-p1); // edge/fiber intersection point, on edge + if (xy_line_line_intersection(p1, p2, u, f.p1, f.p2, v)) { // find XY-intersection btw fiber and edge + Point q = p1 + u * (p2 - p1); // edge/fiber intersection point, on edge // Point q = f.p1 + v*(f.p2-f.p1); // q on fiber // from q, go v_cc*xy_tangent, then r*xy_normal, and end up on fiber: // q + v_cc*tangent + r*xy_normal = p1 + t_cl*(p2-p1) - Point xy_tang=p2-p1; - xy_tang.z=0; + Point xy_tang = p2 - p1; + xy_tang.z = 0; xy_tang.xyNormalize(); Point xy_normal = xy_tang.xyPerp(); - Point q1 = q + radius*xy_normal; - Point q2 = q1 + (p2-p1); + Point q1 = q + radius * xy_normal; + Point q2 = q1 + (p2 - p1); double u_cc, t_cl; - if ( xy_line_line_intersection( q1 , q2, u_cc, f.p1, f.p2, t_cl ) ) { - double t_cl1 = t_cl; // cc_tmp1 = q +/- u_cc*(p2-p1); - double t_cl2 = v + (v-t_cl); - if ( calcCCandUpdateInterval(t_cl1, u_cc, q, p1, p2, f, i, f.p1.z+center_height, EDGE_SHAFT) ) + if (xy_line_line_intersection(q1, q2, u_cc, f.p1, f.p2, t_cl)) { + double t_cl1 = t_cl; // cc_tmp1 = q +/- u_cc*(p2-p1); + double t_cl2 = v + (v - t_cl); + if (calcCCandUpdateInterval(t_cl1, u_cc, q, p1, p2, f, i, f.p1.z + center_height, EDGE_SHAFT)) result = true; - if ( calcCCandUpdateInterval(t_cl2, -u_cc, q, p1, p2, f, i, f.p1.z+center_height, EDGE_SHAFT) ) + if (calcCCandUpdateInterval(t_cl2, -u_cc, q, p1, p2, f, i, f.p1.z + center_height, EDGE_SHAFT)) result = true; } } - //std::cout << " shaftEdgePush = " << result << "\n"; + // std::cout << " shaftEdgePush = " << result << "\n"; return result; } // this is the horizontal edge case -bool MillingCutter::horizEdgePush(const Fiber& f, Interval& i, const Point& p1, const Point& p2) const { - bool result=false; +bool MillingCutter::horizEdgePush(const Fiber &f, Interval &i, const Point &p1, const Point &p2) const { + bool result = false; double h = p1.z - f.p1.z; // height of edge above fiber - if ( (h > 0.0) ) { - if ( isZero_tol( p2.z-p1.z ) ) { // this is the horizontal-edge special case - double eff_radius = this->width( h ); // the cutter acts as a cylinder with eff_radius + if ((h > 0.0)) { + if (isZero_tol(p2.z - p1.z)) { // this is the horizontal-edge special case + double eff_radius = this->width(h); // the cutter acts as a cylinder with eff_radius // contact this cylinder/circle against edge in xy-plane - double qt; // fiber is f.p1 + qt*(f.p2-f.p1) - double qv; // line is p1 + qv*(p2-p1) - if (xy_line_line_intersection( p1 , p2, qv, f.p1, f.p2, qt ) ) { - Point q = p1 + qv*(p2-p1); // the intersection point + double qt; // fiber is f.p1 + qt*(f.p2-f.p1) + double qv; // line is p1 + qv*(p2-p1) + if (xy_line_line_intersection(p1, p2, qv, f.p1, f.p2, qt)) { + Point q = p1 + qv * (p2 - p1); // the intersection point // from q, go v-units along tangent, then eff_r*normal, and end up on fiber: // q + ccv*tangent + r*normal = p1 + clt*(p2-p1) double ccv, clt; - Point xy_tang=p2-p1; - xy_tang.z=0; + Point xy_tang = p2 - p1; + xy_tang.z = 0; xy_tang.xyNormalize(); Point xy_normal = xy_tang.xyPerp(); - Point q1 = q+eff_radius*xy_normal; - Point q2 = q1+(p2-p1); - if ( xy_line_line_intersection( q1 , q2, ccv, f.p1, f.p2, clt ) ) { + Point q1 = q + eff_radius * xy_normal; + Point q2 = q1 + (p2 - p1); + if (xy_line_line_intersection(q1, q2, ccv, f.p1, f.p2, clt)) { double t_cl1 = clt; - double t_cl2 = qt + (qt - clt ); - if ( calcCCandUpdateInterval(t_cl1, ccv, q, p1, p2, f, i, f.p1.z, EDGE_HORIZ) ) + double t_cl2 = qt + (qt - clt); + if (calcCCandUpdateInterval(t_cl1, ccv, q, p1, p2, f, i, f.p1.z, EDGE_HORIZ)) result = true; - if ( calcCCandUpdateInterval(t_cl2, -ccv, q, p1, p2, f, i, f.p1.z, EDGE_HORIZ) ) + if (calcCCandUpdateInterval(t_cl2, -ccv, q, p1, p2, f, i, f.p1.z, EDGE_HORIZ)) result = true; } } } } - //std::cout << " horizEdgePush = " << result << "\n"; + // std::cout << " horizEdgePush = " << result << "\n"; return result; } -bool MillingCutter::calcCCandUpdateInterval( double t, double u, const Point& q, const Point& p1, const Point& p2, - const Fiber& f, Interval& i, double height, CCType cctyp) const { - CCPoint cc_tmp = q+u*(p2-p1); +bool MillingCutter::calcCCandUpdateInterval(double t, double u, const Point &q, const Point &p1, const Point &p2, + const Fiber &f, Interval &i, double height, CCType cctyp) const { + CCPoint cc_tmp = q + u * (p2 - p1); cc_tmp.type = cctyp; - return i.update_ifCCinEdgeAndTrue( t, cc_tmp, p1, p2, (cc_tmp.z >= height) ); -} + return i.update_ifCCinEdgeAndTrue(t, cc_tmp, p1, p2, (cc_tmp.z >= height)); +} -bool MillingCutter::pushCutter(const Fiber& f, Interval& i, const Triangle& t) const { - bool v = vertexPush(f,i,t); - bool fa = facetPush(f,i,t); - bool e = edgePush(f,i,t); +bool MillingCutter::pushCutter(const Fiber &f, Interval &i, const Triangle &t) const { + bool v = vertexPush(f, i, t); + bool fa = facetPush(f, i, t); + bool e = edgePush(f, i, t); return v || fa || e; } - // call vertex, facet, and edge drop methods on input Triangle t bool MillingCutter::dropCutter(CLPoint &cl, const Triangle &t) const { bool facet(false), vertex(false), edge(false); /* // alternative ordering of the tests: if (cl.below(t)) vertexDrop(cl,t); - + // optimisation: if we are now above the triangle we don't need facet and edge if ( cl.below(t) ) { - facetDrop(cl,t); + facetDrop(cl,t); edgeDrop(cl,t); }*/ - + if (cl.below(t)) { - facet = facetDrop(cl,t); // if we make contact with the facet... - if (!facet) { // ...then we will not hit an edge/vertex, so don't check for that - vertex = vertexDrop(cl,t); - if ( cl.below(t) ) { - edge = edgeDrop(cl,t); + facet = facetDrop(cl, t); // if we make contact with the facet... + if (!facet) { // ...then we will not hit an edge/vertex, so don't check for that + vertex = vertexDrop(cl, t); + if (cl.below(t)) { + edge = edgeDrop(cl, t); } } } - - return ( facet || vertex || edge ); + + return (facet || vertex || edge); } // TESTING ONLY, don't use for real bool MillingCutter::dropCutterSTL(CLPoint &cl, const STLSurf &s) const { - bool result=false; - BOOST_FOREACH( const Triangle& t, s.tris) { - if ( this->dropCutter(cl,t) ) + bool result = false; + BOOST_FOREACH (const Triangle &t, s.tris) { + if (this->dropCutter(cl, t)) result = true; } - return result; + return result; } // overlap test: does cutter at cl.x cl.y overlap in the xy-plane with triangle t bool MillingCutter::overlaps(Point &cl, const Triangle &t) const { - if ( t.bb.maxpt.x < cl.x-radius ) + if (t.bb.maxpt.x < cl.x - radius) return false; - else if ( t.bb.minpt.x > cl.x+radius ) + else if (t.bb.minpt.x > cl.x + radius) return false; - else if ( t.bb.maxpt.y < cl.y-radius ) + else if (t.bb.maxpt.y < cl.y - radius) return false; - else if ( t.bb.minpt.y > cl.y+radius ) + else if (t.bb.minpt.y > cl.y + radius) return false; else return true; } - -} // end namespace +} // namespace ocl // end file cutter.cpp diff --git a/src/cutters/millingcutter.hpp b/src/cutters/millingcutter.hpp index 02847923..5419c970 100644 --- a/src/cutters/millingcutter.hpp +++ b/src/cutters/millingcutter.hpp @@ -1,23 +1,23 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef MILLING_CUTTER_H #define MILLING_CUTTER_H @@ -26,23 +26,22 @@ #include #include -#include "stlsurf.hpp" +#include "ccpoint.hpp" +#include "clpoint.hpp" #include "fiber.hpp" #include "point.hpp" -#include "clpoint.hpp" -#include "ccpoint.hpp" +#include "stlsurf.hpp" -namespace ocl -{ +namespace ocl { class Triangle; class STLSurf; -// CC_CLZ_Pair is the return type of +// CC_CLZ_Pair is the return type of // CC is the x-coordinate of the cutter-contact point // CLZ is the z-coordinate of the cutter-location point -typedef std::pair< double, double > CC_CLZ_Pair; -typedef std::pair< double, double > DoublePair; +typedef std::pair CC_CLZ_Pair; +typedef std::pair DoublePair; /// /// \brief MillingCutter is a base-class for all milling cutters @@ -50,151 +49,145 @@ typedef std::pair< double, double > DoublePair; class MillingCutter { friend class CompositeCutter; - public: - /// default constructor - MillingCutter() {} - virtual ~MillingCutter() {} - - /// return the diameter of the cutter - inline double getDiameter() const { return diameter; } - /// return the radius of the cutter - inline double getRadius() const { return radius; } - /// return the length of the cutter - inline double getLength() const { return length; } - - /// return a MillingCutter which is larger than *this by d - virtual MillingCutter* offsetCutter(double d) const; - - /// \brief Test if the cutter bounding-box, positioned at cl, - /// overlaps with the bounding-box of Triangle t. - /// works in the xy-plane - bool overlaps(Point &cl, const Triangle &t) const; - - /// \brief drop cutter at (cl.x, cl.y) against the three vertices of Triangle t. - /// calls this->height(r) on the subclass of MillingCutter we are using. - /// if cl.z is too low, updates cl.z so that cutter does not cut any vertex. - bool vertexDrop(CLPoint &cl, const Triangle &t) const; - /// \brief drop cutter at (cl.x, cl.y) against facet of Triangle t - /// calls xy_normal_length(), normal_length(), and center_height() on the subclass. - /// if cl.z is too low, updates cl.z so that cutter does not cut the facet. - /// CompositeCutter may be the only sub-class that needs to reimplement this function. - virtual bool facetDrop(CLPoint &cl, const Triangle &t) const; - /// \brief drop cutter at (cl.x, cl.y) against the three edges of input Triangle t. - /// calls the sub-class MillingCutter::singleEdgeDrop on each edge - /// if cl.z is too low, updates cl.z so that cutter does not cut any edge. - virtual bool edgeDrop(CLPoint& cl, const Triangle &t) const; - /// \brief drop the MillingCutter at Point cl down along the z-axis until it makes contact with Triangle t. - /// This function calls vertexDrop, facetDrop, and edgeDrop to do its job. - /// Follows the template-method, or "self-delegation" design pattern. - /// if cl.z is too low, updates cl.z so that the cutter does not cut Triangle t. - bool dropCutter(CLPoint &cl, const Triangle &t) const; - - /// \brief call dropCutter on all Triangles in an STLSurf - /// drops the MillingCutter at Point cl down along the z-axis - /// until it makes contact with a triangle in the STLSurf s - /// NOTE: no kd-tree optimization, this function will make - /// dropCutter() calls for each and every Triangle in s. - /// NOTE: should not really be used for real work, demo/debug only - bool dropCutterSTL(CLPoint &cl, const STLSurf &s) const; - - /// push cutter along Fiber f against Triangle t by calling vertexPush, facetPush, and edgePush - /// Interval i will be updated so that it contains the interval where the cutter - /// would violate/gouge the Triangle. - /// Return true if contact was made with the Triangle - bool pushCutter(const Fiber& f, Interval& i, const Triangle& t) const; - - /// return a string representation of the MillingCutter - virtual std::string str() const {return "MillingCutter (all derived classes should override this)";} - - protected: - + public: + /// default constructor + MillingCutter() {} + virtual ~MillingCutter() {} + + /// return the diameter of the cutter + inline double getDiameter() const { return diameter; } + /// return the radius of the cutter + inline double getRadius() const { return radius; } + /// return the length of the cutter + inline double getLength() const { return length; } + + /// return a MillingCutter which is larger than *this by d + virtual MillingCutter *offsetCutter(double d) const; + + /// \brief Test if the cutter bounding-box, positioned at cl, + /// overlaps with the bounding-box of Triangle t. + /// works in the xy-plane + bool overlaps(Point &cl, const Triangle &t) const; + + /// \brief drop cutter at (cl.x, cl.y) against the three vertices of Triangle t. + /// calls this->height(r) on the subclass of MillingCutter we are using. + /// if cl.z is too low, updates cl.z so that cutter does not cut any vertex. + bool vertexDrop(CLPoint &cl, const Triangle &t) const; + /// \brief drop cutter at (cl.x, cl.y) against facet of Triangle t + /// calls xy_normal_length(), normal_length(), and center_height() on the subclass. + /// if cl.z is too low, updates cl.z so that cutter does not cut the facet. + /// CompositeCutter may be the only sub-class that needs to reimplement this function. + virtual bool facetDrop(CLPoint &cl, const Triangle &t) const; + /// \brief drop cutter at (cl.x, cl.y) against the three edges of input Triangle t. + /// calls the sub-class MillingCutter::singleEdgeDrop on each edge + /// if cl.z is too low, updates cl.z so that cutter does not cut any edge. + virtual bool edgeDrop(CLPoint &cl, const Triangle &t) const; + /// \brief drop the MillingCutter at Point cl down along the z-axis until it makes contact with Triangle t. + /// This function calls vertexDrop, facetDrop, and edgeDrop to do its job. + /// Follows the template-method, or "self-delegation" design pattern. + /// if cl.z is too low, updates cl.z so that the cutter does not cut Triangle t. + bool dropCutter(CLPoint &cl, const Triangle &t) const; + + /// \brief call dropCutter on all Triangles in an STLSurf + /// drops the MillingCutter at Point cl down along the z-axis + /// until it makes contact with a triangle in the STLSurf s + /// NOTE: no kd-tree optimization, this function will make + /// dropCutter() calls for each and every Triangle in s. + /// NOTE: should not really be used for real work, demo/debug only + bool dropCutterSTL(CLPoint &cl, const STLSurf &s) const; + + /// push cutter along Fiber f against Triangle t by calling vertexPush, facetPush, and edgePush + /// Interval i will be updated so that it contains the interval where the cutter + /// would violate/gouge the Triangle. + /// Return true if contact was made with the Triangle + bool pushCutter(const Fiber &f, Interval &i, const Triangle &t) const; + + /// return a string representation of the MillingCutter + virtual std::string str() const { return "MillingCutter (all derived classes should override this)"; } + + protected: // PUSH-CUTTER - /// push the cutter along Fiber f into contact with the vertices of Triangle t - /// updates Interval i with the interfering/gouging interval. - /// calls singleVertexPush() on the three vertices of Triangle t - virtual bool vertexPush(const Fiber& f, Interval& i, const Triangle& t) const; - - /// push cutter against a single vertex p - bool singleVertexPush(const Fiber& f, Interval& i, const Point& p, CCType cctyp) const; - - /// push cutter along Fiber f into contact with facet of Triangle t, and update Interval i - /// calls generalFacetPush() - virtual bool facetPush(const Fiber& f, Interval& i, const Triangle& t) const; - - /// push cutter with given normal/center/xy_length into contact with Triangle facet - bool generalFacetPush( double normal_length, - double center_height, - double xy_normal_length, - const Fiber& fib, - Interval& i, - const Triangle& t) - const; - - /// push cutter along Fiber f into contact with edges of Triangle t, update Interval i. - /// calls singleEdgePush() on all three edges of Triangle t. - /// return true if a contact with an edge was found - virtual bool edgePush(const Fiber& f, Interval& i, const Triangle& t) const; - - /// push cutter along fiber against a single edge p1-p2 - /// calls horizEdgePush(), shaftEdgePush(), and generalEdgePush() - bool singleEdgePush(const Fiber& f, Interval& i, const Point& p1, const Point& p2) const; - - /// push-cutter horizontal edge case - /// horizontal are much simpler than the general case. - /// we can consider the cutter circular with an effective radius of this->width(h) - bool horizEdgePush(const Fiber& f, Interval& i, const Point& p1, const Point& p2) const; - - /// push-cutter cylindrical shaft case. - /// This is called when the contact is above the sphere/toroid/cone shaped lower part of the cutter - bool shaftEdgePush(const Fiber& f, Interval& i, const Point& p1, const Point& p2) const; - - /// when horizEdgePush and shaftEdgePush fail we must call this general edge-push function. - /// here we do not assume that the p1-p2 edge is oriented in a special direction - virtual bool generalEdgePush(const Fiber& f, - Interval& i, - const Point& p1, - const Point& p2) const { - return false; - } - - /// CCPoint calculation and interval update for push-cutter - bool calcCCandUpdateInterval( double t, double ccv, const Point& q, const Point& p1, const Point& p2, - const Fiber& f, Interval& i, double height, CCType cctyp) const; - + /// push the cutter along Fiber f into contact with the vertices of Triangle t + /// updates Interval i with the interfering/gouging interval. + /// calls singleVertexPush() on the three vertices of Triangle t + virtual bool vertexPush(const Fiber &f, Interval &i, const Triangle &t) const; + + /// push cutter against a single vertex p + bool singleVertexPush(const Fiber &f, Interval &i, const Point &p, CCType cctyp) const; + + /// push cutter along Fiber f into contact with facet of Triangle t, and update Interval i + /// calls generalFacetPush() + virtual bool facetPush(const Fiber &f, Interval &i, const Triangle &t) const; + + /// push cutter with given normal/center/xy_length into contact with Triangle facet + bool generalFacetPush(double normal_length, double center_height, double xy_normal_length, const Fiber &fib, + Interval &i, const Triangle &t) const; + + /// push cutter along Fiber f into contact with edges of Triangle t, update Interval i. + /// calls singleEdgePush() on all three edges of Triangle t. + /// return true if a contact with an edge was found + virtual bool edgePush(const Fiber &f, Interval &i, const Triangle &t) const; + + /// push cutter along fiber against a single edge p1-p2 + /// calls horizEdgePush(), shaftEdgePush(), and generalEdgePush() + bool singleEdgePush(const Fiber &f, Interval &i, const Point &p1, const Point &p2) const; + + /// push-cutter horizontal edge case + /// horizontal are much simpler than the general case. + /// we can consider the cutter circular with an effective radius of this->width(h) + bool horizEdgePush(const Fiber &f, Interval &i, const Point &p1, const Point &p2) const; + + /// push-cutter cylindrical shaft case. + /// This is called when the contact is above the sphere/toroid/cone shaped lower part of the cutter + bool shaftEdgePush(const Fiber &f, Interval &i, const Point &p1, const Point &p2) const; + + /// when horizEdgePush and shaftEdgePush fail we must call this general edge-push function. + /// here we do not assume that the p1-p2 edge is oriented in a special direction + virtual bool generalEdgePush(const Fiber &f, Interval &i, const Point &p1, const Point &p2) const { return false; } + + /// CCPoint calculation and interval update for push-cutter + bool calcCCandUpdateInterval(double t, double ccv, const Point &q, const Point &p1, const Point &p2, const Fiber &f, + Interval &i, double height, CCType cctyp) const; + // DROP-CUTTER - /// drop cutter against edge p1-p2 at xy-distance d from cl - /// translates to cl=(0,0) and rotates edge to be along x-axis - /// for call to singleEdgeDropCanonical() - bool singleEdgeDrop(CLPoint& cl, const Point& p1, const Point& p2, double d) const; - /// edge-drop in the 'canonical' position with cl=(0,0,cl.z) and edge u1-u2 along x-axis. - /// returns x-coordinate of cc-point and cl.z as a CC_CLZ_Pair. - /// must be implemented in a subclass. - virtual CC_CLZ_Pair singleEdgeDropCanonical(const Point& u1, - const Point& u2) const { - return CC_CLZ_Pair(0.0,0.0); // dummy return value, better to throw an exception or assert? - } - + /// drop cutter against edge p1-p2 at xy-distance d from cl + /// translates to cl=(0,0) and rotates edge to be along x-axis + /// for call to singleEdgeDropCanonical() + bool singleEdgeDrop(CLPoint &cl, const Point &p1, const Point &p2, double d) const; + /// edge-drop in the 'canonical' position with cl=(0,0,cl.z) and edge u1-u2 along x-axis. + /// returns x-coordinate of cc-point and cl.z as a CC_CLZ_Pair. + /// must be implemented in a subclass. + virtual CC_CLZ_Pair singleEdgeDropCanonical(const Point &u1, const Point &u2) const { + return CC_CLZ_Pair(0.0, 0.0); // dummy return value, better to throw an exception or assert? + } + // HEIGHT / WIDTH - /// return the height of the cutter at radius r. redefine in subclass. - virtual double height(double r) const {assert(0); return -1;} - /// return the width of the cutter at height h. redefine in subclass. - virtual double width(double h) const {assert(0); return -1;} - + /// return the height of the cutter at radius r. redefine in subclass. + virtual double height(double r) const { + assert(0); + return -1; + } + /// return the width of the cutter at height h. redefine in subclass. + virtual double width(double h) const { + assert(0); + return -1; + } + // DATA - /// xy_normal length that locates the cutter center relative to a cc-point on a facet. - double xy_normal_length; - /// normal length that locates the cutter center relative to a cc-point on a facet. - double normal_length; - /// height of cutter center along z-axis - double center_height; - /// diameter of cutter - double diameter; - /// radius of cutter - double radius; - /// length of cutter - double length; + /// xy_normal length that locates the cutter center relative to a cc-point on a facet. + double xy_normal_length; + /// normal length that locates the cutter center relative to a cc-point on a facet. + double normal_length; + /// height of cutter center along z-axis + double center_height; + /// diameter of cutter + double diameter; + /// radius of cutter + double radius; + /// length of cutter + double length; }; -} // end namespace +} // namespace ocl #endif // end file millingcutter.h diff --git a/src/dropcutter/adaptivepathdropcutter.cpp b/src/dropcutter/adaptivepathdropcutter.cpp index 59e6ae5d..e0265900 100644 --- a/src/dropcutter/adaptivepathdropcutter.cpp +++ b/src/dropcutter/adaptivepathdropcutter.cpp @@ -1,33 +1,32 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #include -#include "millingcutter.hpp" +#include "adaptivepathdropcutter.hpp" #include "clpoint.hpp" +#include "millingcutter.hpp" #include "pointdropcutter.hpp" -#include "adaptivepathdropcutter.hpp" -namespace ocl -{ +namespace ocl { //******** ********************** */ @@ -38,7 +37,7 @@ AdaptivePathDropCutter::AdaptivePathDropCutter() { path = NULL; minimumZ = 0.0; subOp.clear(); - subOp.push_back( new PointDropCutter() ); // we delegate to PointDropCutter, who does the heavy lifting + subOp.push_back(new PointDropCutter()); // we delegate to PointDropCutter, who does the heavy lifting sampling = 0.1; min_sampling = 0.01; cosLimit = 0.999; @@ -50,48 +49,48 @@ AdaptivePathDropCutter::~AdaptivePathDropCutter() { subOp.clear(); } -void AdaptivePathDropCutter::run() { - adaptive_sampling_run(); -} +void AdaptivePathDropCutter::run() { adaptive_sampling_run(); } void AdaptivePathDropCutter::adaptive_sampling_run() { - //std::cout << " apdc::adaptive_sampling_run()... "; - + // std::cout << " apdc::adaptive_sampling_run()... "; + clpoints.clear(); - BOOST_FOREACH( const Span* span, path->span_list ) { // this loop could run in parallel, since spans don't depend on eachother + BOOST_FOREACH (const Span *span, + path->span_list) { // this loop could run in parallel, since spans don't depend on eachother CLPoint start = span->getPoint(0.0); CLPoint stop = span->getPoint(1.0); subOp[0]->run(start); subOp[0]->run(stop); clpoints.push_back(start); - adaptive_sample( span, 0.0, 1.0, start, stop); + adaptive_sample(span, 0.0, 1.0, start, stop); } - //std::cout << " DONE clpoints.size()=" << clpoints.size() << "\n"; + // std::cout << " DONE clpoints.size()=" << clpoints.size() << "\n"; } -void AdaptivePathDropCutter::adaptive_sample(const Span* span, double start_t, double stop_t, CLPoint start_cl, CLPoint stop_cl) { - const double mid_t = start_t + (stop_t-start_t)/2.0; // mid point sample - assert( mid_t > start_t ); assert( mid_t < stop_t ); +void AdaptivePathDropCutter::adaptive_sample(const Span *span, double start_t, double stop_t, CLPoint start_cl, + CLPoint stop_cl) { + const double mid_t = start_t + (stop_t - start_t) / 2.0; // mid point sample + assert(mid_t > start_t); + assert(mid_t < stop_t); CLPoint mid_cl = span->getPoint(mid_t); - //std::cout << " apdc sampling at " << mid_t << "\n"; - subOp[0]->run( mid_cl ); - double fw_step = (stop_cl-start_cl).xyNorm(); - if ( (fw_step > sampling) || // above minimum step-forward, need to sample more - ( (!flat(start_cl,mid_cl,stop_cl)) && (fw_step > min_sampling) ) ) { // OR not flat, and not max sampling - adaptive_sample( span, start_t, mid_t , start_cl, mid_cl ); - adaptive_sample( span, mid_t , stop_t, mid_cl , stop_cl ); + // std::cout << " apdc sampling at " << mid_t << "\n"; + subOp[0]->run(mid_cl); + double fw_step = (stop_cl - start_cl).xyNorm(); + if ((fw_step > sampling) || // above minimum step-forward, need to sample more + ((!flat(start_cl, mid_cl, stop_cl)) && (fw_step > min_sampling))) { // OR not flat, and not max sampling + adaptive_sample(span, start_t, mid_t, start_cl, mid_cl); + adaptive_sample(span, mid_t, stop_t, mid_cl, stop_cl); } else { - clpoints.push_back(stop_cl); + clpoints.push_back(stop_cl); } } -bool AdaptivePathDropCutter::flat(CLPoint& start_cl, CLPoint& mid_cl, CLPoint& stop_cl) { - CLPoint v1 = mid_cl-start_cl; - CLPoint v2 = stop_cl-mid_cl; +bool AdaptivePathDropCutter::flat(CLPoint &start_cl, CLPoint &mid_cl, CLPoint &stop_cl) { + CLPoint v1 = mid_cl - start_cl; + CLPoint v2 = stop_cl - mid_cl; v1.normalize(); v2.normalize(); return (v1.dot(v2) > cosLimit); } -} // end namespace - +} // namespace ocl diff --git a/src/dropcutter/adaptivepathdropcutter.hpp b/src/dropcutter/adaptivepathdropcutter.hpp index 15baf723..ea900cbc 100644 --- a/src/dropcutter/adaptivepathdropcutter.hpp +++ b/src/dropcutter/adaptivepathdropcutter.hpp @@ -1,97 +1,88 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef ADAPTIVEPATHDROPCUTTER_H #define ADAPTIVEPATHDROPCUTTER_H #include -#include #include +#include #include +#include "clpoint.hpp" +#include "path.hpp" #include "pathdropcutter.hpp" #include "pointdropcutter.hpp" -#include "path.hpp" -#include "clpoint.hpp" -namespace ocl -{ - +namespace ocl { + class MillingCutter; class STLSurf; class Triangle; - /// /// \brief path drop cutter finish Path generation class AdaptivePathDropCutter : public Operation { - public: - /// construct an empty PathDropCutter object - AdaptivePathDropCutter(); - virtual ~AdaptivePathDropCutter(); - - /// run drop-cutter on the whole Path - virtual void run(); - /// set the minimum sapling interval - void setMinSampling(double s) { - assert( s > 0.0 ); - //std::cout << " apdc::setMinSampling = " << s << "\n"; - min_sampling=s; - } - /// set the cosine limit for the flat() predicate - void setCosLimit(double lim) {cosLimit=lim;} - void setZ(const double z) { - minimumZ = z; - } - double getZ() const { - return minimumZ; - } - void setPath(const Path* p) { - path = p; - - subOp[0]->clearCLPoints(); - } - std::vector getPoints() const - { - return clpoints; - } + public: + /// construct an empty PathDropCutter object + AdaptivePathDropCutter(); + virtual ~AdaptivePathDropCutter(); + + /// run drop-cutter on the whole Path + virtual void run(); + /// set the minimum sapling interval + void setMinSampling(double s) { + assert(s > 0.0); + // std::cout << " apdc::setMinSampling = " << s << "\n"; + min_sampling = s; + } + /// set the cosine limit for the flat() predicate + void setCosLimit(double lim) { cosLimit = lim; } + void setZ(const double z) { minimumZ = z; } + double getZ() const { return minimumZ; } + void setPath(const Path *p) { + path = p; + + subOp[0]->clearCLPoints(); + } + std::vector getPoints() const { return clpoints; } - protected: - /// run adaptive sample on the given Span between t-values of start_t and stop_t - void adaptive_sample(const Span* span, double start_t, double stop_t, CLPoint start_cl, CLPoint stop_cl); - /// flatness predicate for adaptive sampling - bool flat(CLPoint& start_cl, CLPoint& mid_cl, CLPoint& stop_cl); - /// run adaptive sampling - void adaptive_sampling_run(); + protected: + /// run adaptive sample on the given Span between t-values of start_t and stop_t + void adaptive_sample(const Span *span, double start_t, double stop_t, CLPoint start_cl, CLPoint stop_cl); + /// flatness predicate for adaptive sampling + bool flat(CLPoint &start_cl, CLPoint &mid_cl, CLPoint &stop_cl); + /// run adaptive sampling + void adaptive_sampling_run(); // DATA - /// the smallest sampling interval used when adaptively subdividing - double min_sampling; - /// the limit for dot-product used in flat() - double cosLimit; - const Path* path; - double minimumZ; - std::vector clpoints; + /// the smallest sampling interval used when adaptively subdividing + double min_sampling; + /// the limit for dot-product used in flat() + double cosLimit; + const Path *path; + double minimumZ; + std::vector clpoints; }; -} // end namespace +} // namespace ocl #endif // end file pathdropcutter.h diff --git a/src/dropcutter/batchdropcutter.cpp b/src/dropcutter/batchdropcutter.cpp index bbc49054..ef1d4107 100644 --- a/src/dropcutter/batchdropcutter.cpp +++ b/src/dropcutter/batchdropcutter.cpp @@ -1,36 +1,35 @@ /* $Id$ - * + * * Copyright (c) 2010-2011 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #include #ifdef _OPENMP // this should really not be a check for Windows, but a check for OpenMP - #include +#include #endif +#include "batchdropcutter.hpp" #include "point.hpp" #include "triangle.hpp" -#include "batchdropcutter.hpp" -namespace ocl -{ +namespace ocl { //******** ********************** */ @@ -45,35 +44,31 @@ BatchDropCutter::BatchDropCutter() { root = new KDTree(); } -BatchDropCutter::~BatchDropCutter() { +BatchDropCutter::~BatchDropCutter() { clpoints->clear(); delete clpoints; delete root; } - + void BatchDropCutter::setSTL(const STLSurf &s) { // std::cout << "bdc::setSTL()\n"; surf = &s; root->setXYDimensions(); // we search for triangles in the XY plane, don't care about Z-coordinate - root->setBucketSize( bucketSize ); + root->setBucketSize(bucketSize); root->build(s.tris); // std::cout << "bdc::setSTL() done.\n"; } - - -void BatchDropCutter::appendPoint(CLPoint& p) { - clpoints->push_back(p); -} +void BatchDropCutter::appendPoint(CLPoint &p) { clpoints->push_back(p); } // drop cutter against all triangles in surface void BatchDropCutter::dropCutter1() { - // std::cout << "dropCutterSTL1 " << clpoints->size() << + // std::cout << "dropCutterSTL1 " << clpoints->size() << // " cl-points and " << surf->tris.size() << " triangles..."; nCalls = 0; - BOOST_FOREACH(CLPoint &cl, *clpoints) { - BOOST_FOREACH( const Triangle& t, surf->tris) {// test against all triangles in s - cutter->dropCutter(cl,t); + BOOST_FOREACH (CLPoint &cl, *clpoints) { + BOOST_FOREACH (const Triangle &t, surf->tris) { // test against all triangles in s + cutter->dropCutter(cl, t); ++nCalls; } } @@ -84,20 +79,20 @@ void BatchDropCutter::dropCutter1() { // first search for triangles under the cutter // then only drop cutter against found triangles void BatchDropCutter::dropCutter2() { - // std::cout << "dropCutterSTL2 " << clpoints->size() << + // std::cout << "dropCutterSTL2 " << clpoints->size() << // " cl-points and " << surf->tris.size() << " triangles.\n"; std::cout.flush(); nCalls = 0; std::list *triangles_under_cutter; - BOOST_FOREACH(CLPoint &cl, *clpoints) { //loop through each CL-point - triangles_under_cutter = root->search_cutter_overlap( cutter , &cl); - BOOST_FOREACH( const Triangle& t, *triangles_under_cutter) { - cutter->dropCutter(cl,t); + BOOST_FOREACH (CLPoint &cl, *clpoints) { // loop through each CL-point + triangles_under_cutter = root->search_cutter_overlap(cutter, &cl); + BOOST_FOREACH (const Triangle &t, *triangles_under_cutter) { + cutter->dropCutter(cl, t); ++nCalls; } delete triangles_under_cutter; } - + // std::cout << "done. " << nCalls << " dropCutter() calls.\n"; std::cout.flush(); return; @@ -105,79 +100,80 @@ void BatchDropCutter::dropCutter2() { // compared to dropCutter2, add an additional explicit overlap-test before testing triangle void BatchDropCutter::dropCutter3() { - // std::cout << "dropCutterSTL3 " << clpoints->size() << + // std::cout << "dropCutterSTL3 " << clpoints->size() << // " cl-points and " << surf->tris.size() << " triangles.\n"; nCalls = 0; std::list *triangles_under_cutter; - BOOST_FOREACH(CLPoint &cl, *clpoints) { //loop through each CL-point - triangles_under_cutter = root->search_cutter_overlap( cutter , &cl); - BOOST_FOREACH( const Triangle& t, *triangles_under_cutter) { - if (cutter->overlaps(cl,t)) { - if ( cl.below(t) ) { - cutter->dropCutter(cl,t); + BOOST_FOREACH (CLPoint &cl, *clpoints) { // loop through each CL-point + triangles_under_cutter = root->search_cutter_overlap(cutter, &cl); + BOOST_FOREACH (const Triangle &t, *triangles_under_cutter) { + if (cutter->overlaps(cl, t)) { + if (cl.below(t)) { + cutter->dropCutter(cl, t); ++nCalls; } } } delete triangles_under_cutter; } - + // std::cout << "done. " << nCalls << " dropCutter() calls.\n"; return; } // use OpenMP to share work between threads void BatchDropCutter::dropCutter4() { - // std::cout << "dropCutterSTL4 " << clpoints->size() << + // std::cout << "dropCutterSTL4 " << clpoints->size() << // " cl-points and " << surf->tris.size() << " triangles.\n"; nCalls = 0; - int calls=0; - std::list* tris; + int calls = 0; + std::list *tris; #ifdef _WIN32 // OpenMP version 2 of VS2013 OpenMP need signed loop variable - int n; // loop variable + int n; // loop variable int Nmax = static_cast(clpoints->size()); #else - unsigned int n; // loop variable + unsigned int n; // loop variable unsigned int Nmax = clpoints->size(); #endif - std::vector& clref = *clpoints; + std::vector &clref = *clpoints; #ifdef _OPENMP omp_set_num_threads(nthreads); // the constructor sets number of threads right // or the user can explicitly specify something else #endif std::list::iterator it; - #pragma omp parallel for shared( calls, clref) private(n,tris,it) - for (n=0;n< Nmax ;n++) { // PARALLEL OpenMP loop! -// #ifdef _OPENMP -// if ( n== 0 ) { // first iteration -// if (omp_get_thread_num() == 0 ) -// std::cout << "Number of OpenMP threads = "<< omp_get_num_threads() << "\n";// print out how many threads we are using -// } -// #endif - tris = root->search_cutter_overlap( cutter, &clref[n] ); - // assert( tris->size() <= ntriangles ); // can't possibly find more triangles than in the STLSurf - for( it=tris->begin(); it!=tris->end() ; ++it) { // loop over found triangles - if ( cutter->overlaps(clref[n],*it) ) { // cutter overlap triangle? check - if (clref[n].below(*it)) { - cutter->vertexDrop( clref[n],*it); - ++calls; - } +#pragma omp parallel for shared(calls, clref) private(n, tris, it) + for (n = 0; n < Nmax; n++) { // PARALLEL OpenMP loop! + // #ifdef _OPENMP + // if ( n== 0 ) { // first iteration + // if (omp_get_thread_num() == 0 ) + // std::cout << "Number of OpenMP threads = "<< omp_get_num_threads() << "\n";// print out + // how many threads we are using + // } + // #endif + tris = root->search_cutter_overlap(cutter, &clref[n]); + // assert( tris->size() <= ntriangles ); // can't possibly find more triangles than in the STLSurf + for (it = tris->begin(); it != tris->end(); ++it) { // loop over found triangles + if (cutter->overlaps(clref[n], *it)) { // cutter overlap triangle? check + if (clref[n].below(*it)) { + cutter->vertexDrop(clref[n], *it); + ++calls; } } - for( it=tris->begin(); it!=tris->end() ; ++it) { // loop over found triangles - if ( cutter->overlaps(clref[n],*it) ) { // cutter overlap triangle? check - if (clref[n].below(*it)) - cutter->facetDrop( clref[n],*it); - } + } + for (it = tris->begin(); it != tris->end(); ++it) { // loop over found triangles + if (cutter->overlaps(clref[n], *it)) { // cutter overlap triangle? check + if (clref[n].below(*it)) + cutter->facetDrop(clref[n], *it); } - for( it=tris->begin(); it!=tris->end() ; ++it) { // loop over found triangles - if ( cutter->overlaps(clref[n],*it) ) { // cutter overlap triangle? check - if (clref[n].below(*it)) - cutter->edgeDrop( clref[n],*it); - } + } + for (it = tris->begin(); it != tris->end(); ++it) { // loop over found triangles + if (cutter->overlaps(clref[n], *it)) { // cutter overlap triangle? check + if (clref[n].below(*it)) + cutter->edgeDrop(clref[n], *it); } - delete( tris ); - } // end OpenMP PARALLEL for + } + delete (tris); + } // end OpenMP PARALLEL for nCalls = calls; // std::cout << " " << nCalls << " dropCutter() calls.\n"; return; @@ -185,50 +181,50 @@ void BatchDropCutter::dropCutter4() { // use OpenMP to share work between threads void BatchDropCutter::dropCutter5() { - // std::cout << "dropCutterSTL5 " << clpoints->size() << + // std::cout << "dropCutterSTL5 " << clpoints->size() << // " cl-points and " << surf->tris.size() << " triangles.\n"; nCalls = 0; - int calls=0; - std::list* tris; + int calls = 0; + std::list *tris; #ifdef _WIN32 // OpenMP version 2 of VS2013 OpenMP need signed loop variable int Nmax = static_cast(clpoints->size()); - int n; // loop variable + int n; // loop variable #else unsigned int Nmax = clpoints->size(); - unsigned int n; // loop variable + unsigned int n; // loop variable #endif - std::vector& clref = *clpoints; - + std::vector &clref = *clpoints; + #ifdef _OPENMP omp_set_num_threads(nthreads); // the constructor sets number of threads right // or the user can explicitly specify something else #endif std::list::iterator it; - #pragma omp parallel for schedule(dynamic) shared( calls, clref ) private(n,tris,it) - for (n=0;nsearch_cutter_overlap( cutter, &clref[n] ); - assert( tris ); - // assert( tris->size() <= ntriangles ); // can't possibly find more triangles than in the STLSurf - for( it=tris->begin(); it!=tris->end() ; ++it) { // loop over found triangles - if ( cutter->overlaps(clref[n],*it) ) { // cutter overlap triangle? check - if (clref[n].below(*it)) { - cutter->dropCutter( clref[n],*it); - ++calls; - } +#pragma omp parallel for schedule(dynamic) shared(calls, clref) private(n, tris, it) + for (n = 0; n < Nmax; ++n) { // PARALLEL OpenMP loop! + // #ifdef _OPENMP + // if ( n== 0 ) { // first iteration + // if (omp_get_thread_num() == 0 ) + // std::cout << "Number of OpenMP threads = "<< omp_get_num_threads() << "\n"; + // } + // #endif + tris = root->search_cutter_overlap(cutter, &clref[n]); + assert(tris); + // assert( tris->size() <= ntriangles ); // can't possibly find more triangles than in the STLSurf + for (it = tris->begin(); it != tris->end(); ++it) { // loop over found triangles + if (cutter->overlaps(clref[n], *it)) { // cutter overlap triangle? check + if (clref[n].below(*it)) { + cutter->dropCutter(clref[n], *it); + ++calls; } } - delete( tris ); - } // end OpenMP PARALLEL for + } + delete (tris); + } // end OpenMP PARALLEL for nCalls = calls; // std::cout << "\n " << nCalls << " dropCutter() calls.\n"; return; } -}// end namespace +} // namespace ocl // end file batchdropcutter.cpp diff --git a/src/dropcutter/batchdropcutter.hpp b/src/dropcutter/batchdropcutter.hpp index 9db01ce5..8b196a53 100644 --- a/src/dropcutter/batchdropcutter.hpp +++ b/src/dropcutter/batchdropcutter.hpp @@ -1,23 +1,23 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef BDC_H #define BDC_H @@ -27,17 +27,15 @@ #include #include "clpoint.hpp" -#include "millingcutter.hpp" #include "kdtree.hpp" +#include "millingcutter.hpp" #include "operation.hpp" -namespace ocl -{ +namespace ocl { class STLSurf; class Triangle; - /// /// BatchDropCutter takes a MillingCutter, an STLSurf, and a list of CLPoint's /// and calls MillingCutter::dropCutter() for each CLPoint. @@ -46,38 +44,37 @@ class Triangle; /// as corresponding CCPoint's /// Some versions of this algorithm use OpenMP for multi-threading. class BatchDropCutter : public Operation { - public: - BatchDropCutter(); - virtual ~BatchDropCutter(); - /// set the STL-surface and build kd-tree to enable optimized algorithm - void setSTL(const STLSurf &s); - /// append to list of CL-points to evaluate - void appendPoint(CLPoint& p); - /// run drop-cutter on all clpoints - void run() {this->dropCutter5();}; + public: + BatchDropCutter(); + virtual ~BatchDropCutter(); + /// set the STL-surface and build kd-tree to enable optimized algorithm + void setSTL(const STLSurf &s); + /// append to list of CL-points to evaluate + void appendPoint(CLPoint &p); + /// run drop-cutter on all clpoints + void run() { this->dropCutter5(); }; // getters and setters - /// return a vector of CLPoints, the result of this operation - std::vector getCLPoints() {return *clpoints;} - /// clears the vector of CLPoints - void clearCLPoints() {clpoints->clear();} - - protected: - /// unoptimized drop-cutter, tests against all triangles of surface - void dropCutter1(); - /// better, kd-tree optimized version - void dropCutter2(); - /// kd-tree and explicit overlap test - void dropCutter3(); - /// use OpenMP for multi-threading - void dropCutter4(); - /// version 5 of the algorithm - void dropCutter5(); - // DATA - /// pointer to list of CL-points on which to run drop-cutter. - std::vector* clpoints; + /// return a vector of CLPoints, the result of this operation + std::vector getCLPoints() { return *clpoints; } + /// clears the vector of CLPoints + void clearCLPoints() { clpoints->clear(); } + protected: + /// unoptimized drop-cutter, tests against all triangles of surface + void dropCutter1(); + /// better, kd-tree optimized version + void dropCutter2(); + /// kd-tree and explicit overlap test + void dropCutter3(); + /// use OpenMP for multi-threading + void dropCutter4(); + /// version 5 of the algorithm + void dropCutter5(); + // DATA + /// pointer to list of CL-points on which to run drop-cutter. + std::vector *clpoints; }; -} // end namespace +} // namespace ocl #endif diff --git a/src/dropcutter/pathdropcutter.cpp b/src/dropcutter/pathdropcutter.cpp index 83fe5b27..bb4e2b78 100644 --- a/src/dropcutter/pathdropcutter.cpp +++ b/src/dropcutter/pathdropcutter.cpp @@ -1,32 +1,31 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #include -#include "millingcutter.hpp" #include "clpoint.hpp" +#include "millingcutter.hpp" #include "pathdropcutter.hpp" -namespace ocl -{ +namespace ocl { //******** ********************** */ @@ -36,7 +35,7 @@ PathDropCutter::PathDropCutter() { path = NULL; minimumZ = 0.0; subOp.clear(); - subOp.push_back( new BatchDropCutter() ); // we delegate to BatchDropCutter, who does the heavy lifting + subOp.push_back(new BatchDropCutter()); // we delegate to BatchDropCutter, who does the heavy lifting sampling = 0.1; } @@ -51,33 +50,30 @@ void PathDropCutter::setPath(const Path *p) { subOp[0]->clearCLPoints(); } -void PathDropCutter::run() { - uniform_sampling_run(); - -} +void PathDropCutter::run() { uniform_sampling_run(); } void PathDropCutter::uniform_sampling_run() { clpoints.clear(); - BOOST_FOREACH( const Span* span, path->span_list ) { // loop through the spans calling run() on each - this->sample_span(span); // append points to bdc + BOOST_FOREACH (const Span *span, path->span_list) { // loop through the spans calling run() on each + this->sample_span(span); // append points to bdc } subOp[0]->run(); clpoints = subOp[0]->getCLPoints(); } // this samples the Span and pushes the corresponding sampled points to bdc -void PathDropCutter::sample_span(const Span* span) { - assert( sampling > 0.0 ); +void PathDropCutter::sample_span(const Span *span) { + assert(sampling > 0.0); unsigned int num_steps = (unsigned int)(span->length2d() / sampling + 1); - for(unsigned int i = 0; i<=num_steps; i++) { + for (unsigned int i = 0; i <= num_steps; i++) { double fraction = (double)i / num_steps; Point ptmp = span->getPoint(fraction); - CLPoint* p = new CLPoint(ptmp.x, ptmp.y, ptmp.z); + CLPoint *p = new CLPoint(ptmp.x, ptmp.y, ptmp.z); p->z = minimumZ; - subOp[0]->appendPoint( *p ); + subOp[0]->appendPoint(*p); delete p; - } + } } -} // end namespace +} // namespace ocl // end file pathdropcutter.cpp diff --git a/src/dropcutter/pathdropcutter.hpp b/src/dropcutter/pathdropcutter.hpp index 0fd0bcbb..6701e5fd 100644 --- a/src/dropcutter/pathdropcutter.hpp +++ b/src/dropcutter/pathdropcutter.hpp @@ -1,81 +1,74 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef PATHDROPCUTTER_H #define PATHDROPCUTTER_H #include -#include #include +#include #include "batchdropcutter.hpp" -#include "path.hpp" #include "operation.hpp" +#include "path.hpp" + +namespace ocl { -namespace ocl -{ - class MillingCutter; class STLSurf; class Triangle; -//class KDNode; +// class KDNode; /// /// \brief path drop cutter finish Path generation class PathDropCutter : public Operation { - public: - /// construct an empty PathDropCutter object - PathDropCutter(); - virtual ~PathDropCutter(); - /// set the Path to follow and sample - void setPath(const Path* path); - /// set the minimum z-value, or "floor" for drop-cutter - void setZ(const double z) { - minimumZ = z; - } - /// return Z - double getZ() const { - return minimumZ; - } - std::vector getPoints() const - { - return clpoints; - } - /// run drop-cutter on the whole Path - virtual void run(); + public: + /// construct an empty PathDropCutter object + PathDropCutter(); + virtual ~PathDropCutter(); + /// set the Path to follow and sample + void setPath(const Path *path); + /// set the minimum z-value, or "floor" for drop-cutter + void setZ(const double z) { minimumZ = z; } + /// return Z + double getZ() const { return minimumZ; } + std::vector getPoints() const { return clpoints; } + /// run drop-cutter on the whole Path + virtual void run(); + + protected: + /// the path to follow + const Path *path; + /// the lowest z height, used when no triangles are touched, default is minimumZ = 0.0 + double minimumZ; + /// list of CL-points + std::vector clpoints; - protected: - /// the path to follow - const Path* path; - /// the lowest z height, used when no triangles are touched, default is minimumZ = 0.0 - double minimumZ; - /// list of CL-points - std::vector clpoints; - private: - /// the algorithm - void uniform_sampling_run(); - /// sample the span unfirormly with tolerance sampling - void sample_span(const Span* span); + private: + /// the algorithm + void uniform_sampling_run(); + /// sample the span unfirormly with tolerance sampling + void sample_span(const Span *span); }; -} // end namespace +} // namespace ocl #endif // end file pathdropcutter.h diff --git a/src/dropcutter/pointdropcutter.cpp b/src/dropcutter/pointdropcutter.cpp index 5ec2431b..9e64db89 100644 --- a/src/dropcutter/pointdropcutter.cpp +++ b/src/dropcutter/pointdropcutter.cpp @@ -1,37 +1,35 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #include -#ifdef _OPENMP - #include +#ifdef _OPENMP +#include #endif #include "point.hpp" -#include "triangle.hpp" #include "pointdropcutter.hpp" +#include "triangle.hpp" - -namespace ocl -{ +namespace ocl { //******** ********************** */ @@ -46,39 +44,39 @@ PointDropCutter::PointDropCutter() { } void PointDropCutter::setSTL(const STLSurf &s) { - //std::cout << "PointDropCutter::setSTL()\n"; + // std::cout << "PointDropCutter::setSTL()\n"; surf = &s; root->setXYDimensions(); // we search for triangles in the XY plane, don't care about Z-coordinate - root->setBucketSize( bucketSize ); + root->setBucketSize(bucketSize); root->build(s.tris); } -void PointDropCutter::run(CLPoint& clp) { - //std::cout << "PointDropCutter::run() clp= " << clp << " dropped to "; +void PointDropCutter::run(CLPoint &clp) { + // std::cout << "PointDropCutter::run() clp= " << clp << " dropped to "; pointDropCutter1(clp); - //std::cout << clp << " nCalls = " << nCalls <<"\n "; + // std::cout << clp << " nCalls = " << nCalls <<"\n "; } // use OpenMP to share work between threads -void PointDropCutter::pointDropCutter1(CLPoint& clp) { +void PointDropCutter::pointDropCutter1(CLPoint &clp) { nCalls = 0; - int calls=0; - std::list* tris; - //tris=new std::list(); - tris = root->search_cutter_overlap( cutter, &clp ); + int calls = 0; + std::list *tris; + // tris=new std::list(); + tris = root->search_cutter_overlap(cutter, &clp); std::list::iterator it; - for( it=tris->begin(); it!=tris->end() ; ++it) { // loop over found triangles - if ( cutter->overlaps(clp,*it) ) { // cutter overlap triangle? check + for (it = tris->begin(); it != tris->end(); ++it) { // loop over found triangles + if (cutter->overlaps(clp, *it)) { // cutter overlap triangle? check if (clp.below(*it)) { - cutter->dropCutter(clp,*it); + cutter->dropCutter(clp, *it); ++calls; } } } - delete( tris ); + delete (tris); nCalls = calls; return; } -}// end namespace +} // namespace ocl // end file pointdropcutter.cpp diff --git a/src/dropcutter/pointdropcutter.hpp b/src/dropcutter/pointdropcutter.hpp index 2e3af191..c829c01c 100644 --- a/src/dropcutter/pointdropcutter.hpp +++ b/src/dropcutter/pointdropcutter.hpp @@ -1,23 +1,23 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef POINTDROPCUTTER_H #define POINTDROPCUTTER_H @@ -26,36 +26,35 @@ #include #include "clpoint.hpp" -#include "millingcutter.hpp" #include "kdtree.hpp" +#include "millingcutter.hpp" #include "operation.hpp" -namespace ocl -{ +namespace ocl { class STLSurf; class Triangle; /// run drop-cutter on an STL-surface at a single input CLPoint class PointDropCutter : public Operation { - public: - PointDropCutter(); - virtual ~PointDropCutter() { - //std::cout << " ~PointDropCutter() \n"; - delete root; - } - void setSTL(const STLSurf &s); - void run(CLPoint& cl); - void run() { - std::cout << "ERROR: can't call run() on PointDropCutter()\n"; - assert(0); - } - - protected: - /// first simple implementation of this operation - void pointDropCutter1(CLPoint& clp); + public: + PointDropCutter(); + virtual ~PointDropCutter() { + // std::cout << " ~PointDropCutter() \n"; + delete root; + } + void setSTL(const STLSurf &s); + void run(CLPoint &cl); + void run() { + std::cout << "ERROR: can't call run() on PointDropCutter()\n"; + assert(0); + } + + protected: + /// first simple implementation of this operation + void pointDropCutter1(CLPoint &clp); }; -} // end namespace +} // namespace ocl #endif diff --git a/src/emscriptenlib/emscriptenlib.cpp b/src/emscriptenlib/emscriptenlib.cpp index 7adec359..282974f0 100644 --- a/src/emscriptenlib/emscriptenlib.cpp +++ b/src/emscriptenlib/emscriptenlib.cpp @@ -2,43 +2,42 @@ #include // GEOMETRY -#include "point.hpp" +#include "bbox.hpp" #include "ccpoint.hpp" #include "clpoint.hpp" -#include "triangle.hpp" -#include "bbox.hpp" -#include "path.hpp" -#include "line.hpp" #include "ellipse.hpp" #include "ellipseposition.hpp" +#include "line.hpp" +#include "path.hpp" +#include "point.hpp" +#include "triangle.hpp" // STL -#include "stlsurf.hpp" #include "stlreader.hpp" +#include "stlsurf.hpp" // ALGO -#include "operation.hpp" -#include "waterline.hpp" #include "adaptivepathdropcutter.hpp" -#include "compositecutter.hpp" #include "adaptivewaterline.hpp" -#include "zigzag.hpp" -#include "weave.hpp" +#include "compositecutter.hpp" #include "lineclfilter.hpp" +#include "operation.hpp" +#include "waterline.hpp" +#include "weave.hpp" +#include "zigzag.hpp" // #include "clsurface.hpp" // CUTTERS -#include "millingcutter.hpp" -#include "cylcutter.hpp" #include "ballcutter.hpp" #include "bullcutter.hpp" #include "conecutter.hpp" +#include "cylcutter.hpp" +#include "millingcutter.hpp" using namespace emscripten; using namespace ocl; -EMSCRIPTEN_BINDINGS(opencamlib) -{ +EMSCRIPTEN_BINDINGS(opencamlib) { ////////////// // GEOMETRY // ////////////// @@ -78,9 +77,7 @@ EMSCRIPTEN_BINDINGS(opencamlib) .function("__str__", &CCPoint::str); // .property("type", &CCPoint::type) // @todo figure out the problem - class_("Triangle") - .constructor() - .constructor(); + class_("Triangle").constructor().constructor(); enum_("CCType") .value("NONE", NONE) @@ -102,8 +99,7 @@ EMSCRIPTEN_BINDINGS(opencamlib) .value("FACET_CYL", FACET_CYL) .value("ERROR", ERROR); - class_("STLReader") - .constructor(); + class_("STLReader").constructor(); class_("STLSurf") .constructor() @@ -142,9 +138,7 @@ EMSCRIPTEN_BINDINGS(opencamlib) .property("c", &Arc::c) .property("dir", &Arc::dir); - enum_("SpanType") - .value("LineSpanType", LineSpanType) - .value("ArcSpanType", ArcSpanType); + enum_("SpanType").value("LineSpanType", LineSpanType).value("ArcSpanType", ArcSpanType); class_("Path") .constructor() @@ -228,8 +222,7 @@ EMSCRIPTEN_BINDINGS(opencamlib) .function("empty", &Interval::empty) .function("__str__", &Interval::str); - class_("Fiber") - .constructor(); + class_("Fiber").constructor(); // class_>("Fiber") // .constructor() @@ -333,20 +326,14 @@ EMSCRIPTEN_BINDINGS(opencamlib) .constructor() .function("dropCutterSTL", &BallCutter::dropCutterSTL, allow_raw_pointers()); - class_>("BullCutter") - .constructor(); - class_>("ConeCutter") - .constructor(); + class_>("BullCutter").constructor(); + class_>("ConeCutter").constructor(); - class_>("CompCylCutter") - .constructor(); - class_>("CompBallCutter") - .constructor(); + class_>("CompCylCutter").constructor(); + class_>("CompBallCutter").constructor(); - class_>("CylConeCutter") - .constructor(); - class_>("BallConeCutter") - .constructor(); + class_>("CylConeCutter").constructor(); + class_>("BallConeCutter").constructor(); class_>("BullConeCutter") .constructor(); class_>("ConeConeCutter") diff --git a/src/geo/arc.cpp b/src/geo/arc.cpp index d81f8cd0..9cb80504 100644 --- a/src/geo/arc.cpp +++ b/src/geo/arc.cpp @@ -1,43 +1,42 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ -#include #include "arc.hpp" +#include -namespace ocl -{ +namespace ocl { Arc::Arc(const Point &p1in, const Point &p2in, const Point &cin, bool dirin) { - p1=p1in; - p2=p2in; - c=cin; - dir=dirin; + p1 = p1in; + p2 = p2in; + c = cin; + dir = dirin; setProperties(); } Arc::Arc(const Arc &a) { - p1=a.p1; - p2=a.p2; - c=a.c; - dir=a.dir; + p1 = a.p1; + p2 = a.p2; + c = a.c; + dir = a.dir; setProperties(); } @@ -51,46 +50,46 @@ void Arc::setProperties() { length = fabs(xyIncludedAngle(vs, ve, dir)) * radius; } -std::ostream& operator<<(std::ostream &stream, const Arc& a) -{ - stream << "(" << a.p1 << ", " << a.p2 << ", " << a.c << ", " << a.dir << ")"; - return stream; +std::ostream &operator<<(std::ostream &stream, const Arc &a) { + stream << "(" << a.p1 << ", " << a.p2 << ", " << a.c << ", " << a.dir << ")"; + return stream; } -Point Arc::getPoint(double t)const { - /// returns a point which is 0-1 along span - if(fabs(t) < 0.00000000000001) +Point Arc::getPoint(double t) const { + /// returns a point which is 0-1 along span + if (fabs(t) < 0.00000000000001) return p1; - if(fabs(t - 1.0) < 0.00000000000001) + if (fabs(t - 1.0) < 0.00000000000001) return p2; - double d = t * length; - if(!dir)d = -d; - Point v = p1 - c; - v.xyRotate(d / radius); - return v + c; + double d = t * length; + if (!dir) + d = -d; + Point v = p1 - c; + v.xyRotate(d / radius); + return v + c; } -double Arc::xyIncludedAngle(const Point& v1, const Point& v2, bool dir) { - // returns the absolute included angle between 2 vectors in +double Arc::xyIncludedAngle(const Point &v1, const Point &v2, bool dir) { + // returns the absolute included angle between 2 vectors in // the direction of dir ( true=acw false=cw ) int d = dir ? 1 : (-1); double inc_ang = v1.dot(v2); - if(inc_ang > 1. - 1.0e-10) + if (inc_ang > 1. - 1.0e-10) return 0; - if(inc_ang < -1. + 1.0e-10) + if (inc_ang < -1. + 1.0e-10) inc_ang = PI; - else { // dot product, v1 . v2 = cos(alfa) - if(inc_ang > 1.0) + else { // dot product, v1 . v2 = cos(alfa) + if (inc_ang > 1.0) inc_ang = 1.0; inc_ang = acos(inc_ang); // 0 to pi radians - double x = v1.x * v2.y - v1.y * v2.x; - if(d * x < 0) - inc_ang = 2 * PI - inc_ang ; // cp + double x = v1.x * v2.y - v1.y * v2.x; + if (d * x < 0) + inc_ang = 2 * PI - inc_ang; // cp } return d * inc_ang; } -} // end namespace +} // namespace ocl // end file arc.cpp diff --git a/src/geo/arc.hpp b/src/geo/arc.hpp index 64c17c33..9342b25c 100644 --- a/src/geo/arc.hpp +++ b/src/geo/arc.hpp @@ -1,74 +1,74 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef ARC_H #define ARC_H -#include "point.hpp" #include "numeric.hpp" +#include "point.hpp" -namespace ocl -{ +namespace ocl { /// /// \brief a finite arc segment in 3D space specified by its end points (p1, p2) /// class Arc { - /// 2D length of the segment in the xy-plane - double length; // 2d length - /// radius of the arc - double radius; + /// 2D length of the segment in the xy-plane + double length; // 2d length + /// radius of the arc + double radius; + + public: + Arc() {} + /// create an arc from point p1 to point p2 with center c and direction dir. + /// direction is true for anti-clockwise arcs. + Arc(const Point &p1, const Point &p2, const Point &c, bool dir); + /// copy constructor + Arc(const Arc &a); + virtual ~Arc(){}; + + /// text output + friend std::ostream &operator<<(std::ostream &stream, const Arc &a); + + /// start point + Point p1; + /// end point + Point p2; + /// centre point + Point c; + /// direction true for anti-clockwise + bool dir; + /// return the length of the arc + double length2d() const { return length; } + /// return a point along the arc at parameter value t [0,1] + Point getPoint(double t) const; - public: - Arc(){} - /// create an arc from point p1 to point p2 with center c and direction dir. - /// direction is true for anti-clockwise arcs. - Arc(const Point &p1, const Point &p2, const Point &c, bool dir); - /// copy constructor - Arc(const Arc &a); - virtual ~Arc() {}; - - /// text output - friend std::ostream& operator<<(std::ostream &stream, const Arc &a); + /// returns the absolute included angle (in radians) between + /// two vectors v1 and v2 in the direction of dir ( true=acw false=cw) + double xyIncludedAngle(const Point &v1, const Point &v2, bool dir = true); - /// start point - Point p1; - /// end point - Point p2; - /// centre point - Point c; - /// direction true for anti-clockwise - bool dir; - /// return the length of the arc - double length2d()const{return length;} - /// return a point along the arc at parameter value t [0,1] - Point getPoint(double t)const; - - /// returns the absolute included angle (in radians) between - /// two vectors v1 and v2 in the direction of dir ( true=acw false=cw) - double xyIncludedAngle(const Point& v1, const Point& v2, bool dir = true); - private: - /// set arc-properties - void setProperties(); + private: + /// set arc-properties + void setProperties(); }; -} // end namespace +} // namespace ocl #endif // end file arc.h diff --git a/src/geo/bbox.cpp b/src/geo/bbox.cpp index 927b1df6..c984f1ea 100644 --- a/src/geo/bbox.cpp +++ b/src/geo/bbox.cpp @@ -1,23 +1,23 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #include @@ -25,29 +25,26 @@ #include "point.hpp" #include "triangle.hpp" -namespace ocl -{ +namespace ocl { //************* axis-aligned Bounding-Box **************/ Bbox::Bbox() { - minpt = Point(0,0,0); - maxpt = Point(0,0,0); + minpt = Point(0, 0, 0); + maxpt = Point(0, 0, 0); initialized = false; } // minx maxx miny maxy minz maxz Bbox::Bbox(double b1, double b2, double b3, double b4, double b5, double b6) { - minpt = Point(b1,b3,b5); - maxpt = Point(b2,b4,b6); + minpt = Point(b1, b3, b5); + maxpt = Point(b2, b4, b6); initialized = true; } -void Bbox::clear() { - initialized = false; -} +void Bbox::clear() { initialized = false; } -bool Bbox::isInside(Point& p) const { - assert( initialized ); +bool Bbox::isInside(Point &p) const { + assert(initialized); if (p.x > maxpt.x) return false; else if (p.x < minpt.x) @@ -74,12 +71,12 @@ void Bbox::addPoint(const Point &p) { maxpt.x = p.x; if (p.x < minpt.x) minpt.x = p.x; - + if (p.y > maxpt.y) maxpt.y = p.y; if (p.y < minpt.y) minpt.y = p.y; - + if (p.z > maxpt.z) maxpt.z = p.z; if (p.z < minpt.z) @@ -87,21 +84,21 @@ void Bbox::addPoint(const Point &p) { } } -/// add each vertex of the Triangle -void Bbox::addTriangle(const Triangle &t) { - addPoint( t.p[0] ); - addPoint( t.p[1] ); - addPoint( t.p[2] ); +/// add each vertex of the Triangle +void Bbox::addTriangle(const Triangle &t) { + addPoint(t.p[0]); + addPoint(t.p[1]); + addPoint(t.p[2]); return; } /// does this Bbox overlap with b? -bool Bbox::overlaps(const Bbox& b) const { - if ( (this->maxpt.x < b.minpt.x) || (this->minpt.x > b.maxpt.x) ) +bool Bbox::overlaps(const Bbox &b) const { + if ((this->maxpt.x < b.minpt.x) || (this->minpt.x > b.maxpt.x)) return false; - else if ( (this->maxpt.y < b.minpt.y) || (this->minpt.y > b.maxpt.y) ) + else if ((this->maxpt.y < b.minpt.y) || (this->minpt.y > b.maxpt.y)) return false; - else if ( (this->maxpt.z < b.minpt.z) || (this->minpt.z > b.maxpt.z) ) + else if ((this->maxpt.z < b.minpt.z) || (this->minpt.z > b.maxpt.z)) return false; else return true; @@ -110,40 +107,40 @@ bool Bbox::overlaps(const Bbox& b) const { // return the bounding box values as a vector: // 0 1 2 3 4 5 // [minx maxx miny maxy minz maxz] -double Bbox::operator[](const unsigned int idx) const{ - switch(idx) { - case 0: - return minpt.x; - break; - case 1: - return maxpt.x; - break; - case 2: - return minpt.y; - break; - case 3: - return maxpt.y; - break; - case 4: - return minpt.z; - break; - case 5: - return maxpt.z; - break; - default: - assert(0); - break; +double Bbox::operator[](const unsigned int idx) const { + switch (idx) { + case 0: + return minpt.x; + break; + case 1: + return maxpt.x; + break; + case 2: + return minpt.y; + break; + case 3: + return maxpt.y; + break; + case 4: + return minpt.z; + break; + case 5: + return maxpt.z; + break; + default: + assert(0); + break; } assert(0); return -1; } std::ostream &operator<<(std::ostream &stream, const Bbox b) { - stream << " Bbox \n"; - stream << " min= "<< b.minpt <<"\n"; - stream << " max= "<< b.maxpt <<"\n"; - return stream; + stream << " Bbox \n"; + stream << " min= " << b.minpt << "\n"; + stream << " max= " << b.maxpt << "\n"; + return stream; } -} // end namespace +} // namespace ocl // end of file volume.cpp diff --git a/src/geo/bbox.hpp b/src/geo/bbox.hpp index c54b476c..5dba4d04 100644 --- a/src/geo/bbox.hpp +++ b/src/geo/bbox.hpp @@ -1,78 +1,77 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef BBOX_H #define BBOX_H #include "point.hpp" -namespace ocl -{ - +namespace ocl { + class Triangle; /// axis-aligned bounding-box class Bbox { - public: - /// default constructor - Bbox(); - /// explicit constructor - Bbox(double b1, double b2, double b3, double b4, double b5, double b6); - virtual ~Bbox() {}; - + public: + /// default constructor + Bbox(); + /// explicit constructor + Bbox(double b1, double b2, double b3, double b4, double b5, double b6); + virtual ~Bbox(){}; + + /// index into maxpt and minpt returning a vector + /// [minx maxx miny maxy minz maxz] + double operator[](const unsigned int idx) const; + + /// return true if Point p is inside this Bbox + bool isInside(Point &p) const; + + /// return true if *this overlaps Bbox b + bool overlaps(const Bbox &other) const; + + /// reset the Bbox (sets initialized=false) + void clear(); + + /// Add a Point to the Bbox. + /// This enlarges the Bbox so that p is contained within it. + void addPoint(const Point &p); + + /// Add each vertex of a Triangle to the Bbox. + /// This enlarges the Bbox so that the Triangle is contained within it. + /// Calls addPoint() for each vertex of the Triangle. + void addTriangle(const Triangle &t); + + friend std::ostream &operator<<(std::ostream &stream, const Bbox b); + + // DATA + /// the maximum point + Point maxpt; + /// the minimum point + Point minpt; - /// index into maxpt and minpt returning a vector - /// [minx maxx miny maxy minz maxz] - double operator[](const unsigned int idx) const; - - /// return true if Point p is inside this Bbox - bool isInside(Point& p) const; - - /// return true if *this overlaps Bbox b - bool overlaps(const Bbox& other) const; - - /// reset the Bbox (sets initialized=false) - void clear(); - - /// Add a Point to the Bbox. - /// This enlarges the Bbox so that p is contained within it. - void addPoint(const Point& p); - - /// Add each vertex of a Triangle to the Bbox. - /// This enlarges the Bbox so that the Triangle is contained within it. - /// Calls addPoint() for each vertex of the Triangle. - void addTriangle(const Triangle& t); - - friend std::ostream &operator<<(std::ostream& stream, const Bbox b); - -//DATA - /// the maximum point - Point maxpt; - /// the minimum point - Point minpt; - private: - /// false until one Point or one Triangle has been added - bool initialized; + private: + /// false until one Point or one Triangle has been added + bool initialized; }; -} // end namespace +} // namespace ocl #endif // end file bbox.h diff --git a/src/geo/ccpoint.cpp b/src/geo/ccpoint.cpp index 0b6b9d9c..f908c64e 100644 --- a/src/geo/ccpoint.cpp +++ b/src/geo/ccpoint.cpp @@ -1,61 +1,45 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #include // for str() #include "ccpoint.hpp" -namespace ocl -{ - +namespace ocl { + /* ********************************************** CCPoint *************/ -CCPoint::CCPoint() - : Point() { - type = NONE; -} +CCPoint::CCPoint() : Point() { type = NONE; } -CCPoint::CCPoint(const Point& p) - : Point( p ) { - type = NONE; -} +CCPoint::CCPoint(const Point &p) : Point(p) { type = NONE; } -CCPoint::CCPoint(const Point& p, CCType t) - : Point( p ) { - type = t; -} +CCPoint::CCPoint(const Point &p, CCType t) : Point(p) { type = t; } -CCPoint::CCPoint(double x, double y, double z) - : Point( x,y,z ) { - type = NONE; -} +CCPoint::CCPoint(double x, double y, double z) : Point(x, y, z) { type = NONE; } -CCPoint::CCPoint(double x, double y, double z, CCType t) - : Point( x,y,z ) { - type = t; -} +CCPoint::CCPoint(double x, double y, double z, CCType t) : Point(x, y, z) { type = t; } -CCPoint& CCPoint::operator=(const Point &p) { - x=p.x; - y=p.y; - z=p.z; +CCPoint &CCPoint::operator=(const Point &p) { + x = p.x; + y = p.y; + z = p.z; type = NONE; return *this; } @@ -66,10 +50,10 @@ std::string CCPoint::str() const { return o.str(); } -std::ostream& operator<<(std::ostream &stream, const CCPoint& p) { - stream << "CC(" << p.x << ", " << p.y << ", " << p.z << ", t=" << p.type <<")"; - return stream; +std::ostream &operator<<(std::ostream &stream, const CCPoint &p) { + stream << "CC(" << p.x << ", " << p.y << ", " << p.z << ", t=" << p.type << ")"; + return stream; } -} // end namespace +} // namespace ocl // end file ccpoint.cpp diff --git a/src/geo/ccpoint.hpp b/src/geo/ccpoint.hpp index defabd10..43aa1dcb 100644 --- a/src/geo/ccpoint.hpp +++ b/src/geo/ccpoint.hpp @@ -1,42 +1,54 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef CCPOINT_H #define CCPOINT_H -#include #include +#include #include "point.hpp" -namespace ocl -{ +namespace ocl { /// type of cc-point -enum CCType {NONE, - VERTEX, VERTEX_CYL, - EDGE, EDGE_HORIZ, EDGE_SHAFT, - EDGE_HORIZ_CYL, EDGE_HORIZ_TOR, EDGE_BALL, - EDGE_POS, EDGE_NEG, EDGE_CYL, EDGE_CONE, EDGE_CONE_BASE, - FACET, FACET_TIP, FACET_CYL, - ERROR}; +enum CCType { + NONE, + VERTEX, + VERTEX_CYL, + EDGE, + EDGE_HORIZ, + EDGE_SHAFT, + EDGE_HORIZ_CYL, + EDGE_HORIZ_TOR, + EDGE_BALL, + EDGE_POS, + EDGE_NEG, + EDGE_CYL, + EDGE_CONE, + EDGE_CONE_BASE, + FACET, + FACET_TIP, + FACET_CYL, + ERROR +}; /// /// \brief Cutter-Contact (CC) point. A Point with a CCType. @@ -44,29 +56,29 @@ enum CCType {NONE, /// Cutter-Contact (CC) Point. /// A Point which also contains the type of cutter-contact. class CCPoint : public Point { - public: - /// create a CCPoint at (0,0,0) - CCPoint(); - /// create CCPoint at (x,y,z) - CCPoint(double x,double y,double z); - /// create CCPoint at (x,y,z) with type t - CCPoint(double x,double y,double z, CCType t); - /// create CCPoint at p with type t - CCPoint(const Point& p, CCType t); - /// create a CCPoint at Point p - CCPoint(const Point& p); - virtual ~CCPoint(){}; - - /// specifies the type of the Cutter Contact point. - CCType type; - /// assign coordinates of Point to this CCPoint. sets type=NONE - CCPoint &operator=(const Point &p); - /// string repr - std::string str() const; - /// string repr - friend std::ostream& operator<<(std::ostream &stream, const CCPoint &p); + public: + /// create a CCPoint at (0,0,0) + CCPoint(); + /// create CCPoint at (x,y,z) + CCPoint(double x, double y, double z); + /// create CCPoint at (x,y,z) with type t + CCPoint(double x, double y, double z, CCType t); + /// create CCPoint at p with type t + CCPoint(const Point &p, CCType t); + /// create a CCPoint at Point p + CCPoint(const Point &p); + virtual ~CCPoint(){}; + + /// specifies the type of the Cutter Contact point. + CCType type; + /// assign coordinates of Point to this CCPoint. sets type=NONE + CCPoint &operator=(const Point &p); + /// string repr + std::string str() const; + /// string repr + friend std::ostream &operator<<(std::ostream &stream, const CCPoint &p); }; -} // end namespace +} // namespace ocl #endif // end file ccpoint.h diff --git a/src/geo/clpoint.cpp b/src/geo/clpoint.cpp index 91c00065..d9abcf86 100644 --- a/src/geo/clpoint.cpp +++ b/src/geo/clpoint.cpp @@ -17,68 +17,49 @@ * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ -#include #include #include +#include #include "clpoint.hpp" -namespace ocl -{ +namespace ocl { /* ********************************************** CLPoint *************/ -CLPoint::CLPoint() - : Point() { - cc = new CCPoint(); -} - -CLPoint::CLPoint(double x, double y, double z) - : Point(x,y,z) { - cc = new CCPoint(); -} +CLPoint::CLPoint() : Point() { cc = new CCPoint(); } -CLPoint::CLPoint(double x, double y, double z, CCPoint& ccp) - : Point(x,y,z) { - cc = new CCPoint( ccp ); -} +CLPoint::CLPoint(double x, double y, double z) : Point(x, y, z) { cc = new CCPoint(); } +CLPoint::CLPoint(double x, double y, double z, CCPoint &ccp) : Point(x, y, z) { cc = new CCPoint(ccp); } -CLPoint::CLPoint(const CLPoint& cl) - : Point(cl.x,cl.y,cl.z) { - cc = new CCPoint( *cl.cc ); -} +CLPoint::CLPoint(const CLPoint &cl) : Point(cl.x, cl.y, cl.z) { cc = new CCPoint(*cl.cc); } -CLPoint::CLPoint(const Point& p) - : Point(p.x,p.y,p.z) { - cc = new CCPoint(); -} +CLPoint::CLPoint(const Point &p) : Point(p.x, p.y, p.z) { cc = new CCPoint(); } -CLPoint::~CLPoint() { - delete cc.load(); -} +CLPoint::~CLPoint() { delete cc.load(); } -bool CLPoint::below(const Triangle& t) const { - if (z < t.bb.maxpt.z ) +bool CLPoint::below(const Triangle &t) const { + if (z < t.bb.maxpt.z) return true; else return false; } bool CLPoint::liftZ(const double zin) { - if (zin>z) { - z=zin; + if (zin > z) { + z = zin; return true; } else { return false; } } -bool CLPoint::liftZ(double zin, CCPoint& ccp) { - if (zin>z) { - z=zin; +bool CLPoint::liftZ(double zin, CCPoint &ccp) { + if (zin > z) { + z = zin; auto newCC = new CCPoint(ccp); auto prevCC = cc.load(); auto expected = prevCC; @@ -98,28 +79,28 @@ bool CLPoint::liftZ(double zin, CCPoint& ccp) { } } -bool CLPoint::liftZ_if_InsidePoints(double zin, CCPoint& cc_tmp, const Point& p1,const Point& p2) { - if ( cc_tmp.isInside(p1, p2) ) +bool CLPoint::liftZ_if_InsidePoints(double zin, CCPoint &cc_tmp, const Point &p1, const Point &p2) { + if (cc_tmp.isInside(p1, p2)) return this->liftZ(zin, cc_tmp); return false; } -bool CLPoint::liftZ_if_inFacet(double zin, CCPoint& cc_tmp, const Triangle& t) { - if ( cc_tmp.isInside(t) ) +bool CLPoint::liftZ_if_inFacet(double zin, CCPoint &cc_tmp, const Triangle &t) { + if (cc_tmp.isInside(t)) return this->liftZ(zin, cc_tmp); return false; } -CLPoint& CLPoint::operator=(const CLPoint &clp) { - if (this == &clp) // check for self-assignment +CLPoint &CLPoint::operator=(const CLPoint &clp) { + if (this == &clp) // check for self-assignment return *this; - x=clp.x; - y=clp.y; - z=clp.z; + x = clp.x; + y = clp.y; + z = clp.z; if (cc) { delete cc.load(); } - cc= new CCPoint( *(clp.cc) ); + cc = new CCPoint(*(clp.cc)); return *this; } @@ -127,19 +108,15 @@ const CLPoint CLPoint::operator+(const CLPoint &p) const { return CLPoint(this->x + p.x, this->y + p.y, this->z + p.z); } -const CLPoint CLPoint::operator+(const Point &p) const { - return CLPoint(this->x + p.x, this->y + p.y, this->z + p.z); -} +const CLPoint CLPoint::operator+(const Point &p) const { return CLPoint(this->x + p.x, this->y + p.y, this->z + p.z); } -CCPoint CLPoint::getCC() { - return *cc; -} +CCPoint CLPoint::getCC() { return *cc; } std::string CLPoint::str() const { std::ostringstream o; - o << "CL(" << x << ", " << y << ", " << z << ") cc=" << *cc ; + o << "CL(" << x << ", " << y << ", " << z << ") cc=" << *cc; return o.str(); } -} // end namespace +} // namespace ocl // end file clpoint.cpp diff --git a/src/geo/clpoint.hpp b/src/geo/clpoint.hpp index d712fcec..03f5748e 100644 --- a/src/geo/clpoint.hpp +++ b/src/geo/clpoint.hpp @@ -17,69 +17,67 @@ * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef CLPOINT_H #define CLPOINT_H #include -#include #include +#include -#include "point.hpp" #include "ccpoint.hpp" +#include "point.hpp" #include "triangle.hpp" -namespace ocl -{ +namespace ocl { /// /// \brief Cutter-Location (CL) point. /// class CLPoint : public Point { - public: - /// CLPoint at (0,0,0) - CLPoint(); - /// CLPoint at (x,y,z) - CLPoint(double x, double y, double z); - /// CLPoint at (x,y,z) with CCPoint ccp - CLPoint(double x, double y, double z, CCPoint& ccp); - /// copy constructor - CLPoint(const CLPoint& cl); - /// cl-point at Point p - CLPoint(const Point& p); - virtual ~CLPoint(); - /// Atomic pointer to the corresponding CCPoint, protected against - /// concurrent replacement in liftZ. - std::atomic cc; - /// string repr - std::string str() const; - - /// if cc is in the edge p1-p2, test if clpoint needs to be lifted to z - /// if so, set cc = cc_tmp and return true - bool liftZ_if_InsidePoints(double z, CCPoint& cc_tmp, const Point& p1,const Point& p2); + public: + /// CLPoint at (0,0,0) + CLPoint(); + /// CLPoint at (x,y,z) + CLPoint(double x, double y, double z); + /// CLPoint at (x,y,z) with CCPoint ccp + CLPoint(double x, double y, double z, CCPoint &ccp); + /// copy constructor + CLPoint(const CLPoint &cl); + /// cl-point at Point p + CLPoint(const Point &p); + virtual ~CLPoint(); + /// Atomic pointer to the corresponding CCPoint, protected against + /// concurrent replacement in liftZ. + std::atomic cc; + /// string repr + std::string str() const; - /// if cc in in Triangle facet, test if clpoint needs to be lifted - /// if so, set cc=cc_tmp and return true - bool liftZ_if_inFacet(double z, CCPoint& cc_tmp, const Triangle& t); + /// if cc is in the edge p1-p2, test if clpoint needs to be lifted to z + /// if so, set cc = cc_tmp and return true + bool liftZ_if_InsidePoints(double z, CCPoint &cc_tmp, const Point &p1, const Point &p2); - /// if zin > z, lift CLPoint and update cc-point, and return true - bool liftZ(double zin, CCPoint& ccp); + /// if cc in in Triangle facet, test if clpoint needs to be lifted + /// if so, set cc=cc_tmp and return true + bool liftZ_if_inFacet(double z, CCPoint &cc_tmp, const Triangle &t); - /// if zin > z, lift CLPoint and return true. - bool liftZ(const double zin); + /// if zin > z, lift CLPoint and update cc-point, and return true + bool liftZ(double zin, CCPoint &ccp); + /// if zin > z, lift CLPoint and return true. + bool liftZ(const double zin); - /// return true if cl-point above triangle - bool below(const Triangle& t) const; - /// return the CCPoint (for python) - CCPoint getCC(); - /// assignment - CLPoint &operator=(const CLPoint &p); - /// addition - const CLPoint operator+(const CLPoint &p) const; - const CLPoint operator+(const Point &p) const; + /// return true if cl-point above triangle + bool below(const Triangle &t) const; + /// return the CCPoint (for python) + CCPoint getCC(); + /// assignment + CLPoint &operator=(const CLPoint &p); + /// addition + const CLPoint operator+(const CLPoint &p) const; + const CLPoint operator+(const Point &p) const; }; -} // end namespace +} // namespace ocl #endif // end file clpoint.h diff --git a/src/geo/line.cpp b/src/geo/line.cpp index 7f3d86d5..1b557307 100644 --- a/src/geo/line.cpp +++ b/src/geo/line.cpp @@ -1,52 +1,47 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #include "line.hpp" -namespace ocl -{ +namespace ocl { Line::Line(const Point &p1in, const Point &p2in) { - p1=p1in; - p2=p2in; + p1 = p1in; + p2 = p2in; } Line::Line(const Line &l) { - p1=l.p1; - p2=l.p2; + p1 = l.p1; + p2 = l.p2; } -std::ostream& operator<<(std::ostream &stream, const Line& l) { - stream << "(" << l.p1 << ", " << l.p2 << ")"; - return stream; +std::ostream &operator<<(std::ostream &stream, const Line &l) { + stream << "(" << l.p1 << ", " << l.p2 << ")"; + return stream; } -double Line::length2d()const { - return (p2 - p1).xyNorm(); -} +double Line::length2d() const { return (p2 - p1).xyNorm(); } -Point Line::getPoint(double t) const { - return (p2 - p1) * t + p1; -} +Point Line::getPoint(double t) const { return (p2 - p1) * t + p1; } -Point Line::Near(const Point& p) const { +Point Line::Near(const Point &p) const { // returns the near point from a line on the extended line Point v = p2 - p1; v.normalize(); @@ -54,5 +49,5 @@ Point Line::Near(const Point& p) const { return p1 + (v * dp); } -} // end namespace +} // namespace ocl // end file line.cpp diff --git a/src/geo/line.hpp b/src/geo/line.hpp index 146c3dd3..f41525d2 100644 --- a/src/geo/line.hpp +++ b/src/geo/line.hpp @@ -1,23 +1,23 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef LINE_H #define LINE_H @@ -25,39 +25,37 @@ #include "point.hpp" -namespace ocl -{ - +namespace ocl { /// /// \brief A finite line segment in 3D space specified by its end points (p1, p2) /// class Line { - public: - Line(){}; - /// create a line from p1 to p2 - Line(const Point &p1, const Point &p2); - /// create a copy of line l. - Line(const Line &l); - virtual ~Line() {}; - - /// text output - friend std::ostream& operator<<(std::ostream &stream, const Line &l); - - /// start point - Point p1; - /// end point - Point p2; - - /// return the length of the line-segment in the xy-plane - double length2d()const; - /// return a Point on the Line at parameter value t [0,1] - Point getPoint(double t) const; - /// return the point on the Line which is closest to Point p. - Point Near(const Point& p) const; + public: + Line(){}; + /// create a line from p1 to p2 + Line(const Point &p1, const Point &p2); + /// create a copy of line l. + Line(const Line &l); + virtual ~Line(){}; + + /// text output + friend std::ostream &operator<<(std::ostream &stream, const Line &l); + + /// start point + Point p1; + /// end point + Point p2; + + /// return the length of the line-segment in the xy-plane + double length2d() const; + /// return a Point on the Line at parameter value t [0,1] + Point getPoint(double t) const; + /// return the point on the Line which is closest to Point p. + Point Near(const Point &p) const; }; -} // end namespace +} // namespace ocl #endif // end file line.h diff --git a/src/geo/path.cpp b/src/geo/path.cpp index 60888abd..06bae684 100644 --- a/src/geo/path.cpp +++ b/src/geo/path.cpp @@ -1,46 +1,37 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ - + */ #include "path.hpp" -namespace ocl -{ +namespace ocl { -Path::Path() { -} +Path::Path() {} -Path::Path(const Path &p) { -} +Path::Path(const Path &p) {} -Path::~Path() { -} +Path::~Path() {} -void Path::append(const Line &l) { - span_list.push_back(new LineSpan(l)); -} +void Path::append(const Line &l) { span_list.push_back(new LineSpan(l)); } -void Path::append(const Arc &a) { - span_list.push_back(new ArcSpan(a)); -} +void Path::append(const Arc &a) { span_list.push_back(new ArcSpan(a)); } -} // end namespace +} // namespace ocl // end file path.cpp diff --git a/src/geo/path.hpp b/src/geo/path.hpp index 46808edc..989908b9 100644 --- a/src/geo/path.hpp +++ b/src/geo/path.hpp @@ -1,118 +1,109 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef PATH_H #define PATH_H #include -#include "point.hpp" -#include "line.hpp" #include "arc.hpp" +#include "line.hpp" +#include "point.hpp" -namespace ocl -{ - +namespace ocl { /// Span type -enum SpanType{ - LineSpanType, - ArcSpanType -}; +enum SpanType { LineSpanType, ArcSpanType }; /// \brief A finite curve which returns Point objects along its length. /// /// location along span is based on a parameter t for which 0 <= t <= 1.0 -class Span{ - public: - /// return type of span - virtual SpanType type()const = 0; - /// return the length of the span in the xy-plane - virtual double length2d()const = 0; - /// return a point at parameter value 0 <= t <= 1.0 - virtual Point getPoint(double t) const = 0; // 0.0 to 1.0 - /// avoid gcc 4.7.1 delete-non-virtual-dtor error - virtual ~Span(){} +class Span { + public: + /// return type of span + virtual SpanType type() const = 0; + /// return the length of the span in the xy-plane + virtual double length2d() const = 0; + /// return a point at parameter value 0 <= t <= 1.0 + virtual Point getPoint(double t) const = 0; // 0.0 to 1.0 + /// avoid gcc 4.7.1 delete-non-virtual-dtor error + virtual ~Span() {} }; /// Line Span class LineSpan : public Span { - public: - /// create a line span from Line l - LineSpan(const Line& l) : line(l){} - /// the line - Line line; + public: + /// create a line span from Line l + LineSpan(const Line &l) : line(l) {} + /// the line + Line line; - // Span's virtual functions - /// return span type - SpanType type()const{return LineSpanType;} - /// return span length - double length2d() const { - return line.length2d(); - } - /// return point on span - Point getPoint(double t) const { - return line.getPoint(t); - } + // Span's virtual functions + /// return span type + SpanType type() const { return LineSpanType; } + /// return span length + double length2d() const { return line.length2d(); } + /// return point on span + Point getPoint(double t) const { return line.getPoint(t); } }; /// circular Arc Span class ArcSpan : public Span { - public: - /// create span - ArcSpan(const Arc& a) : arc(a){} - /// arc - Arc arc; + public: + /// create span + ArcSpan(const Arc &a) : arc(a) {} + /// arc + Arc arc; - // Span's virtual functions - /// return type - SpanType type()const{return ArcSpanType;} - /// return length in xy-plane - double length2d()const{return arc.length2d();} - /// return a point on the span - Point getPoint(double t)const{return arc.getPoint(t);} + // Span's virtual functions + /// return type + SpanType type() const { return ArcSpanType; } + /// return length in xy-plane + double length2d() const { return arc.length2d(); } + /// return a point on the span + Point getPoint(double t) const { return arc.getPoint(t); } }; /// /// \brief A collection of Span objects /// class Path { - public: - /// create empty path - Path(); - /// copy constructor - Path(const Path &p); - /// destructor - virtual ~Path(); + public: + /// create empty path + Path(); + /// copy constructor + Path(const Path &p); + /// destructor + virtual ~Path(); - /// list of spans in this path - std::list span_list; + /// list of spans in this path + std::list span_list; - // FIXME: this looks wrong - // should be only one append() that takes a Span - /// append a Line to this path - void append(const Line &l); - /// append an Arc to this path - void append(const Arc &a); + // FIXME: this looks wrong + // should be only one append() that takes a Span + /// append a Line to this path + void append(const Line &l); + /// append an Arc to this path + void append(const Arc &a); }; -} // end namespace +} // namespace ocl #endif // end file path.h diff --git a/src/geo/point.cpp b/src/geo/point.cpp index daf3d33b..a704b93b 100644 --- a/src/geo/point.cpp +++ b/src/geo/point.cpp @@ -1,65 +1,60 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ -#include // sqrt, sin, cos, fabs + */ #include +#include // sqrt, sin, cos, fabs #include +#include "numeric.hpp" #include "point.hpp" #include "triangle.hpp" -#include "numeric.hpp" -namespace ocl -{ - +namespace ocl { + Point::Point() { - x=0; - y=0; - z=0; + x = 0; + y = 0; + z = 0; } Point::Point(double xin, double yin, double zin) { - x=xin; - y=yin; - z=zin; + x = xin; + y = yin; + z = zin; } Point::Point(double xin, double yin) { - x=xin; - y=yin; - z=0.0; + x = xin; + y = yin; + z = 0.0; } Point::Point(const Point &p) { - x=p.x; - y=p.y; - z=p.z; + x = p.x; + y = p.y; + z = p.z; } - //******** methods ********************** */ - -double Point::norm() const { - return sqrt( square(x) + square(y) + square(z) ); -} +double Point::norm() const { return sqrt(square(x) + square(y) + square(z)); } Point Point::cross(const Point &p) const { double xc = y * p.z - z * p.y; @@ -68,140 +63,107 @@ Point Point::cross(const Point &p) const { return Point(xc, yc, zc); } -double Point::dot(const Point &p) const { - return x * p.x + y * p.y + z * p.z; -} +double Point::dot(const Point &p) const { return x * p.x + y * p.y + z * p.z; } void Point::normalize() { if (this->norm() != 0.0) - *this *=(1/this->norm()); + *this *= (1 / this->norm()); } -double Point::xyNorm() const { - return sqrt( square(x) + square(y) ); -} +double Point::xyNorm() const { return sqrt(square(x) + square(y)); } void Point::xyNormalize() { if (this->xyNorm() != 0.0) - *this *=(1/this->xyNorm()); + *this *= (1 / this->xyNorm()); } -Point Point::xyPerp() const -{ - return Point(-y, x, z); -} +Point Point::xyPerp() const { return Point(-y, x, z); } -void Point::xyRotate(double cosa, double sina) { // rotate vector by angle +void Point::xyRotate(double cosa, double sina) { // rotate vector by angle double temp = -y * sina + x * cosa; y = x * sina + cosa * y; x = temp; } -void Point::xyRotate(double angle) { - xyRotate(cos(angle), sin(angle)); -} +void Point::xyRotate(double angle) { xyRotate(cos(angle), sin(angle)); } -void Point::xRotate(double theta) { - matrixRotate(1, 0 , 0 , - 0, cos(theta), -sin(theta), - 0, sin(theta), cos(theta) ); -} +void Point::xRotate(double theta) { matrixRotate(1, 0, 0, 0, cos(theta), -sin(theta), 0, sin(theta), cos(theta)); } -void Point::yRotate(double theta) { - matrixRotate(cos(theta) , 0 , sin(theta) , - 0 , 1 , 0 , - -sin(theta), 0 , cos(theta) ); -} +void Point::yRotate(double theta) { matrixRotate(cos(theta), 0, sin(theta), 0, 1, 0, -sin(theta), 0, cos(theta)); } -void Point::zRotate(double theta) { - matrixRotate(cos(theta), -sin(theta) , 0 , - sin(theta), cos(theta), 0, - 0, 0, 1 ); -} +void Point::zRotate(double theta) { matrixRotate(cos(theta), -sin(theta), 0, sin(theta), cos(theta), 0, 0, 0, 1); } // http://en.wikipedia.org/wiki/Rotation_matrix -void Point::matrixRotate(double a,double b, double c, - double d,double e, double f, - double g,double h, double i) { +void Point::matrixRotate(double a, double b, double c, double d, double e, double f, double g, double h, double i) { // multiply point with matrix - double xr = a*x + b*y + c*z; - double yr = d*x + e*y + f*z; - double zr = g*x + h*y + i*z; - x=xr; - y=yr; - z=zr; + double xr = a * x + b * y + c * z; + double yr = d * x + e * y + f * z; + double zr = g * x + h * y + i * z; + x = xr; + y = yr; + z = zr; } -double Point::xyDistance(const Point &p) const -{ +double Point::xyDistance(const Point &p) const { return (*this - p).xyNorm(); - //return sqrt(pow(x - p.x, 2) + pow((y - p.y), 2)); + // return sqrt(pow(x - p.x, 2) + pow((y - p.y), 2)); } - - - -double Point::xyDistanceToLine(const Point &p1, const Point &p2) const -{ +double Point::xyDistanceToLine(const Point &p1, const Point &p2) const { // see for example // http://mathworld.wolfram.com/Point-LineDistance2-Dimensional.html - if ((p1.x == p2.x) && (p1.y == p2.y)) {// no line in xy plane + if ((p1.x == p2.x) && (p1.y == p2.y)) { // no line in xy plane std::cout << "point.cpp: xyDistanceToLine ERROR!: can't calculate distance from \n"; - std::cout << "point.cpp: xyDistanceToLine ERROR!: *this ="<<*this <<" to line through\n"; - std::cout << "point.cpp: xyDistanceToLine ERROR!: p1="< 0.0 ); - double u = (*this - p1).dot(v) / v.dot(v); // u = (p3-p1) dot v / (v dot v) - return p1 + u*v; + assert(v.norm() > 0.0); + double u = (*this - p1).dot(v) / v.dot(v); // u = (p3-p1) dot v / (v dot v) + return p1 + u * v; } /// return Point on p1-p2 line which is closest in XY-plane to this -Point Point::xyClosestPoint(const Point &p1, const Point &p2) const -{ +Point Point::xyClosestPoint(const Point &p1, const Point &p2) const { // one explanation is here // http://local.wasp.uwa.edu.au/~pbourke/geometry/pointline/ Point pt1 = p1; // this required because of "const" arguments above. Point pt2 = p2; Point v = pt2 - pt1; - if ( isZero_tol( v.xyNorm() ) ) { // if p1 and p2 do not make a line in the xy-plane + if (isZero_tol(v.xyNorm())) { // if p1 and p2 do not make a line in the xy-plane std::cout << "point.cpp: xyClosestPoint ERROR!: can't calculate closest point from \n"; - std::cout << "point.cpp: xyClosestPoint ERROR!: *this ="<<*this <<" to line through\n"; - std::cout << "point.cpp: xyClosestPoint ERROR!: p1="<x - p1.x) * (v.x) + (this->y - p1.y)*(v.y); - u = u/ (v.x*v.x + v.y*v.y); + u = (this->x - p1.x) * (v.x) + (this->y - p1.y) * (v.y); + u = u / (v.x * v.x + v.y * v.y); // coordinates for closest point - double x = p1.x + u*v.x; - double y = p1.y + u*v.y; - return Point(x,y,0); + double x = p1.x + u * v.x; + double y = p1.y + u * v.y; + return Point(x, y, 0); } - -bool Point::isRight(const Point &p1, const Point &p2) const -{ +bool Point::isRight(const Point &p1, const Point &p2) const { // is Point right of line through points p1 and p2 ?, in the XY plane. // this is an ugly way of doing a determinant // should be prettyfied sometime... @@ -217,24 +179,24 @@ bool Point::isRight(const Point &p1, const Point &p2) const if (t > 0.00000000000001) /// \todo FIXME: hardcoded magic number... return true; else - return false; + return false; } bool Point::isInside(const Triangle &t) const { // point in triangle test // http://www.blackpawn.com/texts/pointinpoly/default.html - + Point v0 = t.p[2] - t.p[0]; Point v1 = t.p[1] - t.p[0]; - Point v2 = *this - t.p[0]; - + Point v2 = *this - t.p[0]; + double dot00 = v0.dot(v0); double dot01 = v0.dot(v1); double dot02 = v0.dot(v2); double dot11 = v1.dot(v1); double dot12 = v1.dot(v2); - - double invD = 1.0 / ( dot00 *dot11 - dot01*dot01 ); + + double invD = 1.0 / (dot00 * dot11 - dot01 * dot01); // barycentric coordinates double u = (dot11 * dot02 - dot01 * dot12) * invD; double v = (dot00 * dot12 - dot01 * dot02) * invD; @@ -243,12 +205,12 @@ bool Point::isInside(const Triangle &t) const { return (u > 0.0) && (v > 0.0) && (u + v < 1.0); } -bool Point::isInside(const Point& p1, const Point& p2) const { +bool Point::isInside(const Point &p1, const Point &p2) const { // segment is p1 + t*(p2-p1) // p1 + t*(p2-p1) = p // p1*(p2-p1) + t * (p2-p1)*(p2-p1) = p*(p2-p1) // t = (p - p1 )*(p2-p1) / (p2-p1)*(p2-p1) - double t = (*this - p1).dot( p2-p1 ) / (p2-p1).dot(p2-p1); + double t = (*this - p1).dot(p2 - p1) / (p2 - p1).dot(p2 - p1); if (t > 1.0) return false; else if (t < 0.0) @@ -257,72 +219,56 @@ bool Point::isInside(const Point& p1, const Point& p2) const { return true; } - - - - -/* **************** Operators *************** +/* **************** Operators *************** * see * http://www.cs.caltech.edu/courses/cs11/material/cpp/donnie/cpp-ops.html -*/ + */ -Point& Point::operator=(const Point &p) { +Point &Point::operator=(const Point &p) { if (this == &p) return *this; - x=p.x; - y=p.y; - z=p.z; + x = p.x; + y = p.y; + z = p.z; return *this; } // Point*scalar multiplication -Point& Point::operator*=(const double &a) { - x*=a; - y*=a; - z*=a; +Point &Point::operator*=(const double &a) { + x *= a; + y *= a; + z *= a; return *this; } -Point& Point::operator+=(const Point &p) { - x+=p.x; - y+=p.y; - z+=p.z; +Point &Point::operator+=(const Point &p) { + x += p.x; + y += p.y; + z += p.z; return *this; } -Point& Point::operator-=(const Point &p) { - x-=p.x; - y-=p.y; - z-=p.z; +Point &Point::operator-=(const Point &p) { + x -= p.x; + y -= p.y; + z -= p.z; return *this; } -const Point Point::operator+(const Point &p) const { - return Point(*this) += p; -} +const Point Point::operator+(const Point &p) const { return Point(*this) += p; } -const Point Point::operator-(const Point &p) const { - return Point(*this) -= p; -} +const Point Point::operator-(const Point &p) const { return Point(*this) -= p; } -const Point Point::operator*(const double &a) const { - return Point(*this) *= a; -} +const Point Point::operator*(const double &a) const { return Point(*this) *= a; } // scalar*Point -const Point operator*(const double &a, const Point &p) { - return Point(p) *= a; -} +const Point operator*(const double &a, const Point &p) { return Point(p) *= a; } -bool Point::operator==(const Point &p) const { - return (this == &p) || (x==p.x && y==p.y && z==p.z); -} +bool Point::operator==(const Point &p) const { return (this == &p) || (x == p.x && y == p.y && z == p.z); } -bool Point::operator!=(const Point &p) const { - return !(*this == p); -} +bool Point::operator!=(const Point &p) const { return !(*this == p); } -bool Point::zParallel() const { +bool Point::zParallel() const { if (x != 0.0) return false; else if (y != 0.0) @@ -331,41 +277,40 @@ bool Point::zParallel() const { return true; } -bool Point::xParallel() const { - if ( isZero_tol( y ) && isZero_tol( z ) ) +bool Point::xParallel() const { + if (isZero_tol(y) && isZero_tol(z)) return true; return false; } -bool Point::yParallel() const { - if ( isZero_tol( x ) && isZero_tol( z ) ) +bool Point::yParallel() const { + if (isZero_tol(x) && isZero_tol(z)) return true; return false; } -void Point::z_projectOntoEdge(const Point& p1, const Point& p2) { +void Point::z_projectOntoEdge(const Point &p1, const Point &p2) { // edge is p1+t*(p2-p1) // now locate z-coord of *this on edge double t; - if ( fabs(p2.x-p1.x) > fabs(p2.y-p1.y) ) { - t = (this->x - p1.x) / (p2.x-p1.x); + if (fabs(p2.x - p1.x) > fabs(p2.y - p1.y)) { + t = (this->x - p1.x) / (p2.x - p1.x); } else { - t = (this->y - p1.y) / (p2.y-p1.y); + t = (this->y - p1.y) / (p2.y - p1.y); } - this->z = p1.z + t*(p2.z-p1.z); + this->z = p1.z + t * (p2.z - p1.z); } - std::string Point::str() const { std::ostringstream o; o << *this; return o.str(); } -std::ostream& operator<<(std::ostream &stream, const Point& p) { - stream << "(" << p.x << ", " << p.y << ", " << p.z << ")"; - return stream; +std::ostream &operator<<(std::ostream &stream, const Point &p) { + stream << "(" << p.x << ", " << p.y << ", " << p.z << ")"; + return stream; } -} // end namespace +} // namespace ocl // end file point.cpp diff --git a/src/geo/point.hpp b/src/geo/point.hpp index eac9d691..0d01365b 100644 --- a/src/geo/point.hpp +++ b/src/geo/point.hpp @@ -1,154 +1,150 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef POINT_H #define POINT_H -#include #include +#include -namespace ocl -{ +namespace ocl { -class Triangle; +class Triangle; /// /// \brief a point or vector in 3D space specified by its coordinates (x, y, z) /// class Point { - public: - /// create a point at (0,0,0) - Point(); - /// create a point at (x,y,z) - Point(double x, double y, double z); - /// create a point at (x,y,0) - Point(double x, double y); - /// create a point at p - Point(const Point &p); - /// destructor. empty. - virtual ~Point() {}; - - /// dot product - double dot(const Point &p) const; - - /// cross product - Point cross(const Point &p) const; - - /// norm of vector, or distance from (0,0,0) to *this - double norm() const; - - /// scales vector so that norm()==1.0 - void normalize(); - - /// distance from Point to another Point p in the XY plane - double xyDistance(const Point &p) const; - - /// length of vector in the XY plane - double xyNorm() const; - - /// normalize so that length xyNorm == 1.0 - void xyNormalize(); - - /// return perpendicular in the xy plane, rotated 90 degree to the left - Point xyPerp() const; - - /// move *this along z-axis so it lies on p1-p2 line-segment - void z_projectOntoEdge(const Point& p1, const Point& p2); - - /// rotate point in the xy-plane by angle theta - /// inputs are cos(theta) and sin(theta) - void xyRotate(double cosa, double sina); - /// rotate point in xy-plane bu angle theta (radians or degrees??) - void xyRotate(double angle); - - /// rotate around x-axis - void xRotate(double theta); - /// rotate around y-axis - void yRotate(double theta); - /// rotate around z-axis - void zRotate(double theta); - void matrixRotate(double a,double b, double c, - double d,double e, double f, - double g,double h, double i); - - /// distance from Point to infinite line through p1 and p2. In the XY plane. - double xyDistanceToLine(const Point &p1, const Point &p2) const; - - /// return closest Point to line through p1 and p2. in 3D. - Point closestPoint(const Point &p1, const Point &p2) const; - - /// return closest Point to line through p1 and p2. Works in the XY plane. - Point xyClosestPoint(const Point &p1, const Point &p2) const; - - /// returns true if point is right of line through p1 and p2 (works in the XY-plane) - bool isRight(const Point &p1, const Point &p2) const; - - /// returns true if Point *this is inside Triangle t - bool isInside(const Triangle &t) const; - /// return true if Point within line segment p1-p2 - bool isInside(const Point& p1, const Point& p2) const; - - - /// return true if the x and y components are both zero. - bool xParallel() const; - /// return true if vector parallel to y-axis - bool yParallel() const; - /// return true if vector parallel to z-axis - bool zParallel() const; - - /// assignment - Point &operator=(const Point &p); - /// addition - Point &operator+=(const Point &p); - /// subtraction - Point &operator-=(const Point &p); - /// addition - const Point operator+(const Point &p)const; - /// subtraction - const Point operator-(const Point &p) const; - - /// scalar multiplication - Point &operator*=(const double &a); // scalar multiplication with Point *= scalar - /// Point * scalar - const Point operator*(const double &a)const; // Point*scalar - /// equality - bool operator==(const Point &p) const; - /// inequality - bool operator!=(const Point &p) const; - - /// string repr - friend std::ostream& operator<<(std::ostream &stream, const Point &p); - /// string repr - std::string str() const; - - /// X coordinate - double x; - /// Y coordinate - double y; - /// Z coordinate - double z; + public: + /// create a point at (0,0,0) + Point(); + /// create a point at (x,y,z) + Point(double x, double y, double z); + /// create a point at (x,y,0) + Point(double x, double y); + /// create a point at p + Point(const Point &p); + /// destructor. empty. + virtual ~Point(){}; + + /// dot product + double dot(const Point &p) const; + + /// cross product + Point cross(const Point &p) const; + + /// norm of vector, or distance from (0,0,0) to *this + double norm() const; + + /// scales vector so that norm()==1.0 + void normalize(); + + /// distance from Point to another Point p in the XY plane + double xyDistance(const Point &p) const; + + /// length of vector in the XY plane + double xyNorm() const; + + /// normalize so that length xyNorm == 1.0 + void xyNormalize(); + + /// return perpendicular in the xy plane, rotated 90 degree to the left + Point xyPerp() const; + + /// move *this along z-axis so it lies on p1-p2 line-segment + void z_projectOntoEdge(const Point &p1, const Point &p2); + + /// rotate point in the xy-plane by angle theta + /// inputs are cos(theta) and sin(theta) + void xyRotate(double cosa, double sina); + /// rotate point in xy-plane bu angle theta (radians or degrees??) + void xyRotate(double angle); + + /// rotate around x-axis + void xRotate(double theta); + /// rotate around y-axis + void yRotate(double theta); + /// rotate around z-axis + void zRotate(double theta); + void matrixRotate(double a, double b, double c, double d, double e, double f, double g, double h, double i); + + /// distance from Point to infinite line through p1 and p2. In the XY plane. + double xyDistanceToLine(const Point &p1, const Point &p2) const; + + /// return closest Point to line through p1 and p2. in 3D. + Point closestPoint(const Point &p1, const Point &p2) const; + + /// return closest Point to line through p1 and p2. Works in the XY plane. + Point xyClosestPoint(const Point &p1, const Point &p2) const; + + /// returns true if point is right of line through p1 and p2 (works in the XY-plane) + bool isRight(const Point &p1, const Point &p2) const; + + /// returns true if Point *this is inside Triangle t + bool isInside(const Triangle &t) const; + /// return true if Point within line segment p1-p2 + bool isInside(const Point &p1, const Point &p2) const; + + /// return true if the x and y components are both zero. + bool xParallel() const; + /// return true if vector parallel to y-axis + bool yParallel() const; + /// return true if vector parallel to z-axis + bool zParallel() const; + + /// assignment + Point &operator=(const Point &p); + /// addition + Point &operator+=(const Point &p); + /// subtraction + Point &operator-=(const Point &p); + /// addition + const Point operator+(const Point &p) const; + /// subtraction + const Point operator-(const Point &p) const; + + /// scalar multiplication + Point &operator*=(const double &a); // scalar multiplication with Point *= scalar + /// Point * scalar + const Point operator*(const double &a) const; // Point*scalar + /// equality + bool operator==(const Point &p) const; + /// inequality + bool operator!=(const Point &p) const; + + /// string repr + friend std::ostream &operator<<(std::ostream &stream, const Point &p); + /// string repr + std::string str() const; + + /// X coordinate + double x; + /// Y coordinate + double y; + /// Z coordinate + double z; }; /// scalar multiplication scalar*Point const Point operator*(const double &a, const Point &p); -} // end namespace +} // namespace ocl #endif // end file point.h diff --git a/src/geo/stlreader.cpp b/src/geo/stlreader.cpp index 48797f80..0aa29826 100644 --- a/src/geo/stlreader.cpp +++ b/src/geo/stlreader.cpp @@ -1,160 +1,148 @@ // stlreader.cpp -// +// // Written by Dan Heeks /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ -#include // required by read_from_file() -#include + */ #include +#include // required by read_from_file() #include +#include #include "stlreader.hpp" #include "stlsurf.hpp" -namespace ocl -{ +namespace ocl { - STLReader::STLReader(const std::wstring &filepath, STLSurf& surface) { - read_from_file(filepath.c_str(), surface); - } - - STLReader::~STLReader() { - //delete tris; - } +STLReader::STLReader(const std::wstring &filepath, STLSurf &surface) { read_from_file(filepath.c_str(), surface); } - using namespace std; +STLReader::~STLReader() { + // delete tris; +} - static std::string str_for_Ttc; +using namespace std; - /// consider renaming? - const char* Ttc(const wchar_t* str) - { - // convert a wchar_t* string into a char* string - str_for_Ttc.clear(); - while (*str) - str_for_Ttc.push_back((char) *str++); - return str_for_Ttc.c_str(); - } +static std::string str_for_Ttc; - void STLReader::read_from_file(const wchar_t* filepath, STLSurf& surface) { - // read the stl file - std::ifstream ifs(Ttc(filepath), ios::binary); - if(!ifs)return; - - char solid_string[6] = "aaaaa"; - ifs.read(solid_string, 5); - if(ifs.eof())return; - if(strcmp(solid_string, "solid")) - { - // try binary file read - - // read the header - char header[81]; - header[80] = 0; - memcpy(header, solid_string, 5); - ifs.read(&header[5], 75); - - unsigned int num_facets = 0; - ifs.read((char*)(&num_facets), 4); - - for(unsigned int i = 0; i> x[vertex][0] >> x[vertex][1] >> x[vertex][2]; + std::istringstream ss(str); + ss.imbue(std::locale("C")); + while (ss.peek() == ' ') + ss.seekg(1, ios_base::cur); + ss.seekg(std::string("vertex").size(), ios_base::cur); + ss >> x[vertex][0] >> x[vertex][1] >> x[vertex][2]; #endif - vertex++; - if(vertex > 2)vertex = 2; - } - else if(!strcmp(five_chars, "facet")) - { + vertex++; + if (vertex > 2) + vertex = 2; + } else if (!strcmp(five_chars, "facet")) { #ifdef WIN32 - sscanf_s(str, " facet normal %f %f %f", &(n[0]), &(n[1]), &(n[2])); + sscanf_s(str, " facet normal %f %f %f", &(n[0]), &(n[1]), &(n[2])); #else - std::istringstream ss(str); - ss.imbue(std::locale("C")); - while(ss.peek() == ' ') ss.seekg(1, ios_base::cur); - ss.seekg(std::string("facet normal").size(), ios_base::cur); - ss >> n[0] >> n[1] >> n[2]; + std::istringstream ss(str); + ss.imbue(std::locale("C")); + while (ss.peek() == ' ') + ss.seekg(1, ios_base::cur); + ss.seekg(std::string("facet normal").size(), ios_base::cur); + ss >> n[0] >> n[1] >> n[2]; #endif - vertex = 0; - } - else if(!strcmp(five_chars, "endfa")) - { - if(vertex == 2) - { - surface.addTriangle(Triangle(Point(x[0][0], x[0][1], x[0][2]), - Point(x[1][0], x[1][1], x[1][2]), - Point(x[2][0], x[2][1], x[2][2]))); - } + vertex = 0; + } else if (!strcmp(five_chars, "endfa")) { + if (vertex == 2) { + surface.addTriangle(Triangle(Point(x[0][0], x[0][1], x[0][2]), Point(x[1][0], x[1][1], x[1][2]), + Point(x[2][0], x[2][1], x[2][2]))); } } } } } - } + +} // namespace ocl diff --git a/src/geo/stlreader.hpp b/src/geo/stlreader.hpp index 135faf58..3e3db841 100644 --- a/src/geo/stlreader.hpp +++ b/src/geo/stlreader.hpp @@ -1,49 +1,47 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef STLREADER_H #define STLREADER_H -namespace ocl -{ - -class STLSurf; +namespace ocl { +class STLSurf; /// \brief STL file reader, reads an STL file and calls addTriangle on the STLSurf /// class STLReader { - public: - STLReader(){}; - /// construct with file name and surface to fill - STLReader(const std::wstring &filepath, STLSurf& surface); - /// destructor - virtual ~STLReader(); - - private: - /// read STL-surface from file - void read_from_file(const wchar_t* filepath, STLSurf& surface); + public: + STLReader(){}; + /// construct with file name and surface to fill + STLReader(const std::wstring &filepath, STLSurf &surface); + /// destructor + virtual ~STLReader(); + + private: + /// read STL-surface from file + void read_from_file(const wchar_t *filepath, STLSurf &surface); }; -} +} // namespace ocl #endif diff --git a/src/geo/stlsurf.cpp b/src/geo/stlsurf.cpp index a4a06290..1f983ef8 100644 --- a/src/geo/stlsurf.cpp +++ b/src/geo/stlsurf.cpp @@ -1,67 +1,64 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ -#include #include +#include #include #include "stlsurf.hpp" -namespace ocl -{ +namespace ocl { void STLSurf::addTriangle(const Triangle &t) { - + // some sanity-checking: - assert( (t.p[0]-t.p[1]).norm() > 0.0 ); - assert( (t.p[1]-t.p[2]).norm() > 0.0 ); - assert( (t.p[2]-t.p[0]).norm() > 0.0 ); - + assert((t.p[0] - t.p[1]).norm() > 0.0); + assert((t.p[1] - t.p[2]).norm() > 0.0); + assert((t.p[2] - t.p[0]).norm() > 0.0); + tris.push_back(t); bb.addTriangle(t); return; } void STLSurf::rotate(double xr, double yr, double zr) { - //std::cout << " before " << t << "\n"; + // std::cout << " before " << t << "\n"; bb.clear(); - BOOST_FOREACH(Triangle& t, tris) { - //std::cout << " before " << t << "\n"; - t.rotate(xr,yr,zr); - //std::cout << " after " << t << "\n"; - //char c; - //std::cin >> c; + BOOST_FOREACH (Triangle &t, tris) { + // std::cout << " before " << t << "\n"; + t.rotate(xr, yr, zr); + // std::cout << " after " << t << "\n"; + // char c; + // std::cin >> c; bb.addTriangle(t); - } + } } -unsigned int STLSurf::size() const { - return static_cast(tris.size()); -} +unsigned int STLSurf::size() const { return static_cast(tris.size()); } std::ostream &operator<<(std::ostream &stream, const STLSurf s) { - stream << "STLSurf(N="<< s.tris.size() <<")"; - return stream; + stream << "STLSurf(N=" << s.tris.size() << ")"; + return stream; } -} // end namespace +} // namespace ocl // end file stlsurf.cpp diff --git a/src/geo/stlsurf.hpp b/src/geo/stlsurf.hpp index c0e5a94c..3ce2659f 100644 --- a/src/geo/stlsurf.hpp +++ b/src/geo/stlsurf.hpp @@ -1,34 +1,33 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef STLSURF_H #define STLSURF_H #include -#include "triangle.hpp" #include "bbox.hpp" +#include "triangle.hpp" + +namespace ocl { -namespace ocl -{ - class Point; /// \brief STL surface, essentially an unordered list of Triangle objects @@ -36,25 +35,25 @@ class Point; /// STL surfaces consist of triangles. There is by definition no structure /// or order among the triangles, i.e. they can be positioned or connected in arbitrary ways. class STLSurf { - public: - /// Create an empty STL-surface - STLSurf() {}; - /// destructor - virtual ~STLSurf() {}; - /// add Triangle t to this surface - void addTriangle(const Triangle& t); - /// return number of triangles in surface - unsigned int size() const; - /// call Triangle::rotate on all triangles - void rotate(double xr,double yr, double zr); - /// list of Triangles in this surface - std::list tris; - /// bounding-box - Bbox bb; - /// STLSurf string repr - friend std::ostream &operator<<(std::ostream& stream, const STLSurf s); + public: + /// Create an empty STL-surface + STLSurf(){}; + /// destructor + virtual ~STLSurf(){}; + /// add Triangle t to this surface + void addTriangle(const Triangle &t); + /// return number of triangles in surface + unsigned int size() const; + /// call Triangle::rotate on all triangles + void rotate(double xr, double yr, double zr); + /// list of Triangles in this surface + std::list tris; + /// bounding-box + Bbox bb; + /// STLSurf string repr + friend std::ostream &operator<<(std::ostream &stream, const STLSurf s); }; -} // end namespace +} // namespace ocl #endif // end file stlsurf.h diff --git a/src/geo/triangle.cpp b/src/geo/triangle.cpp index 850ebb14..ec845f08 100644 --- a/src/geo/triangle.cpp +++ b/src/geo/triangle.cpp @@ -1,134 +1,127 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #include #include -#include "triangle.hpp" #include "numeric.hpp" +#include "triangle.hpp" -namespace ocl -{ +namespace ocl { Triangle::Triangle() { - p[0]=Point(1,0,0); - p[1]=Point(0,1,0); - p[2]=Point(0,0,1); + p[0] = Point(1, 0, 0); + p[1] = Point(0, 1, 0); + p[2] = Point(0, 0, 1); calcNormal(); calcBB(); } Triangle::Triangle(Point p1, Point p2, Point p3) { - p[0]=p1; - p[1]=p2; - p[2]=p3; + p[0] = p1; + p[1] = p2; + p[2] = p3; calcNormal(); calcBB(); } Triangle::Triangle(const Triangle &t) { - p[0]=t.p[0]; - p[1]=t.p[1]; - p[2]=t.p[2]; + p[0] = t.p[0]; + p[1] = t.p[1]; + p[2] = t.p[2]; calcNormal(); calcBB(); } - - - /// calculate bounding box values void Triangle::calcBB() { bb.clear(); - bb.addTriangle( *this ); + bb.addTriangle(*this); } /// calculate, normalize, and set the Triangle normal void Triangle::calcNormal() { - Point v1=p[0]-p[1]; - Point v2=p[0]-p[2]; - Point ntemp = v1.cross(v2); // the normal is in the direction of the cross product between the edge vectors - ntemp.normalize(); // FIXME this might fail if norm()==0 - n = Point(ntemp.x,ntemp.y,ntemp.z); + Point v1 = p[0] - p[1]; + Point v2 = p[0] - p[2]; + Point ntemp = v1.cross(v2); // the normal is in the direction of the cross product between the edge vectors + ntemp.normalize(); // FIXME this might fail if norm()==0 + n = Point(ntemp.x, ntemp.y, ntemp.z); } -Point Triangle::upNormal() const { - return (n.z < 0) ? -1.0* n : n; -} +Point Triangle::upNormal() const { return (n.z < 0) ? -1.0 * n : n; } -bool Triangle::zslice_verts(Point& p1, Point& p2, double zcut) const { - if ( (zcut <= this->bb.minpt.z) || ((zcut >= this->bb.maxpt.z)) ) +bool Triangle::zslice_verts(Point &p1, Point &p2, double zcut) const { + if ((zcut <= this->bb.minpt.z) || ((zcut >= this->bb.maxpt.z))) return false; // no zslice // find out how many vertices are below zcut std::vector below; std::vector above; - for (int m=0;m<3;++m) { - if ( p[m].z <= zcut ) + for (int m = 0; m < 3; ++m) { + if (p[m].z <= zcut) below.push_back(p[m]); else above.push_back(p[m]); } - if ( !(below.size() == 1) && !(below.size() == 2) ) { + if (!(below.size() == 1) && !(below.size() == 2)) { std::cout << "triangle.cpp: zslice_verts() error while trying to z-slice\n"; std::cout << " triangle=" << *this << "\n"; std::cout << " zcut=" << zcut << "\n"; std::cout << above.size() << " above points:\n"; - BOOST_FOREACH(Point p, above) { + BOOST_FOREACH (Point p, above) { std::cout << " " << p << "\n"; } std::cout << below.size() << " below points:\n"; - BOOST_FOREACH(Point p, below) { + BOOST_FOREACH (Point p, below) { std::cout << " " << p << "\n"; } } - assert( (below.size() == 1) || (below.size() == 2) ); - - if ( below.size() == 2 ) { - assert( above.size() == 1 ); - // find two new intersection points + assert((below.size() == 1) || (below.size() == 2)); + + if (below.size() == 2) { + assert(above.size() == 1); + // find two new intersection points // edge is p1 + t*(p2-p1) = zcut // so t = zcut-p1 / (p2-p1) double t1 = (zcut - above[0].z) / (below[0].z - above[0].z); // div by zero?! double t2 = (zcut - above[0].z) / (below[1].z - above[0].z); - p1 = above[0] + t1*(below[0] - above[0]); - p2 = above[0] + t2*(below[1] - above[0]); + p1 = above[0] + t1 * (below[0] - above[0]); + p2 = above[0] + t2 * (below[1] - above[0]); return true; - } else if ( below.size() == 1 ) { - assert( above.size() == 2 ); + } else if (below.size() == 1) { + assert(above.size() == 2); // find intersection points and add two new triangles // t = (zcut -p1) / (p2-p1) - double t1 = (zcut - above[0].z) / (below[0].z - above[0].z); + double t1 = (zcut - above[0].z) / (below[0].z - above[0].z); double t2 = (zcut - above[1].z) / (below[0].z - above[1].z); - p1 = above[0] + t1*(below[0]-above[0]); - p2 = above[1] + t2*(below[0]-above[1]); + p1 = above[0] + t1 * (below[0] - above[0]); + p2 = above[1] + t2 * (below[0] - above[1]); return true; } else { assert(0); return false; } - } void Triangle::rotate(double xr, double yr, double zr) { - for (int n=0;n<3;++n) { + for (int n = 0; n < 3; ++n) { p[n].xRotate(xr); p[n].yRotate(yr); p[n].zRotate(zr); @@ -138,9 +131,9 @@ void Triangle::rotate(double xr, double yr, double zr) { } std::ostream &operator<<(std::ostream &stream, const Triangle t) { - stream << "T: " << t.p[0] << " " << t.p[1] << " " << t.p[2] << "n=" << t.n ; - return stream; + stream << "T: " << t.p[0] << " " << t.p[1] << " " << t.p[2] << "n=" << t.n; + return stream; } -} // end namespace +} // namespace ocl // end file triangle.cpp diff --git a/src/geo/triangle.hpp b/src/geo/triangle.hpp index 5d2de0b6..e7d633a3 100644 --- a/src/geo/triangle.hpp +++ b/src/geo/triangle.hpp @@ -1,79 +1,76 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef TRIANGLE_H #define TRIANGLE_H #include -#include "point.hpp" #include "bbox.hpp" +#include "point.hpp" -namespace ocl -{ +namespace ocl { /// /// \brief a Triangle defined by its three vertices /// class Triangle { - public: - /// default constructor - Triangle(); - /// copy constructor - Triangle(const Triangle &t); - - /// destructor - virtual ~Triangle() {} - /// Create a triangle with the vertices p1, p2, and p3. - Triangle(Point p1, Point p2, Point p3); - - /// return true if Triangle is sliced by a z-plane at z=zcut - /// modify p1 and p2 so that they are intesections of the triangle edges - /// and the plane. These vertices are used by CylCutter::edgePush() - bool zslice_verts(Point& p1, Point& p2, double zcut) const; - - /// rotate triangle xrot radians around X-axis, yrot radians around Y-axis - /// and zrot radians around Z-axis - void rotate(double xrot, double yrot, double zrot); - - /// Triangle string repr - friend std::ostream &operator<<(std::ostream &stream, const Triangle t); - - /// the three vertex Points of the Triangle - Point p[3]; // vertices - /// normal vector - Point n; - /// return normal vector with positive z-coordinate - Point upNormal() const; - /// bounding-box - Bbox bb; + public: + /// default constructor + Triangle(); + /// copy constructor + Triangle(const Triangle &t); + + /// destructor + virtual ~Triangle() {} + /// Create a triangle with the vertices p1, p2, and p3. + Triangle(Point p1, Point p2, Point p3); + + /// return true if Triangle is sliced by a z-plane at z=zcut + /// modify p1 and p2 so that they are intesections of the triangle edges + /// and the plane. These vertices are used by CylCutter::edgePush() + bool zslice_verts(Point &p1, Point &p2, double zcut) const; + + /// rotate triangle xrot radians around X-axis, yrot radians around Y-axis + /// and zrot radians around Z-axis + void rotate(double xrot, double yrot, double zrot); + + /// Triangle string repr + friend std::ostream &operator<<(std::ostream &stream, const Triangle t); + /// the three vertex Points of the Triangle + Point p[3]; // vertices + /// normal vector + Point n; + /// return normal vector with positive z-coordinate + Point upNormal() const; + /// bounding-box + Bbox bb; - - protected: - /// calculate and set Triangle normal - void calcNormal(); - /// update bounding-box - void calcBB(); + protected: + /// calculate and set Triangle normal + void calcNormal(); + /// update bounding-box + void calcBB(); }; -} // end namespace +} // namespace ocl #endif // end file triangle.h diff --git a/src/manual.hpp b/src/manual.hpp index 05303910..6c77c64a 100644 --- a/src/manual.hpp +++ b/src/manual.hpp @@ -1,51 +1,51 @@ /* $Id$ -*/ + */ /*! \mainpage OpenCAMLib manual - * + * * \section intro_sec Introduction - * OpenCAMLib is a C++ library with Python bindings under LGPL license + * OpenCAMLib is a C++ library with Python bindings under LGPL license * for creating toolpaths for cnc machines. - * + * * - hosted at: http://code.google.com/p/opencamlib/ * - mailing-list at: http://groups.google.com/group/opencamlib * - svn-commits at: http://groups.google.com/group/opencamlib-svn - * + * * This section describes how to obtain, build, and install OpenCAMLib. - * + * * The \ref usr-manual section describes how to install and use OpenCAMLib. - * + * * The \ref dev-manual section describes the CAM-algorithms in more detail. - * + * * \section install_sec Installation * As of 2010 March there is no release yet. You have to build from source. - * + * * \subsection source Building from source * The project is hosted at google-code: http://code.google.com/p/opencamlib/ - * + * * To checkout the newest OpenCAMLib, run: - * + * * svn checkout http://opencamlib.googlecode.com/svn/trunk/ opencamlib-read-only * - * - * Building requires the Boost libraries and a compiler that supports OpenMP. Visualizations require VTK. + * + * Building requires the Boost libraries and a compiler that supports OpenMP. Visualizations require VTK. * It should be as simple as: - * + * * cmake . - * + * * make - * + * * make install * - * + * * all done! - * + * * \subsubsection ubuntu Debian package On Ubuntu * As of SVN r95, OCL builds easily on Ubuntu Hardy through Karmic. * OCL will build on Lucid with some tweaks, which are not covered in these * brief instructions; proper support for Lucid is planned for the near * future. - * + * * Use apt-get to install some software that helps build Debian packages: * * shell> apt-get install devscripts build-essential @@ -69,63 +69,52 @@ * * \subsubsection windows Building On Windows * Text here on how to build on windows. - * + * * \subsection OCL with CAD-applications * How to get opencamlib installed and working with HeeksCNC. - * + * * How to use OCL with Blender, FreeCAD, etc. */ - - - + /*! \page usr-manual OpenCAMLib user manual - * + * * Here text on how to use the library. - * + * * \section Drop-Cutter * Tutorial and examples using drop-cutter. */ - - - - - - - - - /*! \page dev-manual OpenCAMLib developer manual - * + * * \section intro_dev Introduction * This section of the manual describes the computational geometry and algorithms used in OpenCAMLib. * Three-dimensional points and vectors are denoted with bold. - * + * * \section Drop-Cutter * The drop cutter algorithm drops a cutter, positioned at a predefined (x,y) location * down along the z-axis until it makes contact with a triangle. - * The algorithm is split into three parts, testing the cutter separately against the + * The algorithm is split into three parts, testing the cutter separately against the * three vertices ( vertexDrop() ), three edges ( edgeDrop() ), and the facet ( facetDrop() )of the triangle. * In general the vertex test is trivial, the facet test easy, and the edge test is the most difficult. - * + * * \subsection dc-gen General * A cutter-location cl point is a point where the cutter tip can be located when in contact * with the surface, but without interfering with the STL-surface. * A cutter-contact (cc) point is the point where the cutter makes contact with the STL-surface. - * The user specifies the (cl.x, cl.y) coordinates of the cutter, and an initial value cl.z for the cl z-coordinate. + * The user specifies the (cl.x, cl.y) coordinates of the cutter, and an initial value cl.z for the cl z-coordinate. * The task for the vertex, facet, and edge tests is to update the height of the cutter cl.z. When each vertex, edge, - * and facet of each triangle under the cutter positioned at (cl.x, cl.y) has been tested, the resulting cl.z is the - * correct and final (maximum) height of the cutter we want. If no test finds a contact between the cutter and a triangle, then - * cl.z and cc are left unmodified. - * - * The following milling cutters are supported by opencamlib. They all inherit from the base-class MillingCutter. + * and facet of each triangle under the cutter positioned at (cl.x, cl.y) has been tested, the resulting cl.z is the + * correct and final (maximum) height of the cutter we want. If no test finds a contact between the cutter and a + * triangle, then cl.z and cc are left unmodified. + * + * The following milling cutters are supported by opencamlib. They all inherit from the base-class MillingCutter. * The CompoundCutter class allows specifying any shape similar to a general APT-type cutter. - * + * * All cutters share common data-fields: * - diameter * - radius * - length - * + * * Cutter shapes: * - Cylindrical: CylCutter * - radius = diameter/2 @@ -136,166 +125,158 @@ * - radius2 = the tube-radius of the torus * - radius2 <= radius1 must be true (undefined behavior may occur if radius2>radius1) * - Conical: ConeCutter - * - diameter = maximum diameter of the cone + * - diameter = maximum diameter of the cone * - angle = half-angle of the cone, in radians. For a 90-degree cutter, set angle = pi/4 * - Compound: combinations of the above (restricted to an overall convex cutter shape). For example: * - ConeConeCutter * - BallConeCutter * - BullConeCutter - * + * * \subsection verttest Vertex test * Milling cutters are symmetrical around their axis of rotation (the z-axis in 3-axis milling), so the vertex * test only depends on the distance between the cutter axis and the test-vertex. - * Given cl and a vertex p to test, calculate the distance d in the xy-plane from cl to p: + * Given cl and a vertex p to test, calculate the distance d in the xy-plane from cl to p: * \f[ * d = |cl - p| = \sqrt{(cl.x-p.x)^2+(cl.y-p.y)^2} * \f] * If \f$d > radius\f$ the cutter will not contact the vertex and we return without modifying cl.z. * If \f$d <= radius\f$ the cutter will make contact with the vertex. - * - * - Cylindrical cutters are flat we can set \f$cl.z = p.z\f$ + * + * - Cylindrical cutters are flat we can set \f$cl.z = p.z\f$ * - For a Spherical cutter (see FigureX) \f$h = r - \sqrt{ r^2 - d^2 }\f$ and we set \f$cl.z = p.z - h\f$ * - For Toroidal cutters: * - If \f$d < r_1\f$ we are in the cylindrical part of the cutter and set \f$cl.z = p.z\f$ - * - If \f$r_1 < d < r\f$ we are in the toroidal part and \f$ h = r_2 - \sqrt{ r_2^2 - (d-r_1)^2 }\f$ and then \f$cl.z = p.z - h\f$ + * - If \f$r_1 < d < r\f$ we are in the toroidal part and \f$ h = r_2 - \sqrt{ r_2^2 - (d-r_1)^2 }\f$ and then + * \f$cl.z = p.z - h\f$ * - For Conical cutters: * - \f$h = d/tan(angle)\f$ and set \f$cl.z = p.z - h\f$ * In all cases cc = p. (TODO: insert image of vertex test here) - * - * - * - * + * + * + * + * * \subsection facettest Facet test * Call the three vertices of the triangle p1, p2, and p3. * The facet test is really a test against the whole plane which contains the triangle facet. * First calculate the normal n of the facet, and normalize its length to one. The equation for the - * plane is given by + * plane is given by * \f[ * a*x + b*y + c*z + d = 0 * \f] - * where the coefficients \f$(a, b, c) = \bar{n}\f$. The constant d can be calculated by inserting one vertex + * where the coefficients \f$(a, b, c) = \bar{n}\f$. The constant d can be calculated by inserting one vertex * into the formula of the plane: \f$d = -\bar{n}\cdot \bar{p_1}\f$. - * - * Also calculate and normalize the xy-projection of the normal \f$\bar{n_{xy}}\f$. + * + * Also calculate and normalize the xy-projection of the normal \f$\bar{n_{xy}}\f$. * Note that vertical facets with n.z = 0 are a special case which are ignored in the drop-cutter algorithm. - * + * * \subsubsection cylfacettest Cylindrical cutter facet test * The contact point with the plane will lie on the periphery of the cutter, a - * distance \f$radius\f$ from \f$(cl.x, cl.y)\f$ in the direction \f$-\bar{n_{xy}}\f$, so the xy-coordinates of + * distance \f$radius\f$ from \f$(cl.x, cl.y)\f$ in the direction \f$-\bar{n_{xy}}\f$, so the xy-coordinates of * the cc-point are given by: * \f[ * (cc.x, cc.y) = (cl.x, cl.y) - r*\bar{n_{xy}} * \f] - * This cc-point lies on the plane, but not necessarily in the facet of the triangle. + * This cc-point lies on the plane, but not necessarily in the facet of the triangle. * If the cc-point is contained within the triangle (in the xy-plane), we can calculate its z-coordinate by * inserting into the equation of the plane: * \f[ * cc.z = (1/c)*(-d-a*cc.x-b*cc.y) - * \f] - * Since the cylindrical endmill is flat, we can also set \f$cl.z = cc.z\f$. + * \f] + * Since the cylindrical endmill is flat, we can also set \f$cl.z = cc.z\f$. * Note division by \f$c\f$ which requires \f$c = n.z \neq 0\f$ - * + * * \subsubsection sphfacettest Spherical cutter facet test - * The center of the sphere is located a distance \f$radius\f$ from \f$(cl.x, cl.y)\f$ in the direction of \f$-\bar{n}\f$. - * We can find out the xy-compontents of the cc point with: - * \f[ - * \bar{cc} = \bar{cl} - r*\bar{n} - * \f] - * If this point lies within the facet of the triangle we locate the point on the plane by setting cc.z on the plane: - * \f[ + * The center of the sphere is located a distance \f$radius\f$ from \f$(cl.x, cl.y)\f$ in the direction of + * \f$-\bar{n}\f$. We can find out the xy-compontents of the cc point with: \f[ \bar{cc} = \bar{cl} - r*\bar{n} \f] If + * this point lies within the facet of the triangle we locate the point on the plane by setting cc.z on the plane: \f[ * cc.z = (1/c)*(-d-a*cc.x-b*cc.y) - * \f] + * \f] * The tool-tip z-coordinate is now given by \f$cl.z = cc.z + r*(n\cdot\hat{z}) - r \f$ - * - * + * + * * \subsubsection torfacettest Toroidal cutter facet test * Define a vector which points from the cc-point to the center of the toroid. This is a distance \f$radius2\f$ * along the surface normal \bar{n} and a distance \f$radius1\f$ along the XY-normal \bar{n_{xy}}: * \f[ * \bar{R} = r_2*\bar{n} + r_1* \bar{n_{xy}} - * \f] + * \f] * Now the xy-coordinates of the cc-point are given by * \f[ * \bar{cc} = \bar{cl} - \bar{R} - * \f] + * \f] * now check if this cc-point lies in the facet of the plane. If so, the z-coordinate of the cc-point is calculated: * \f[ * cc.z = (1/c)*(-d-a*cc.x-b*cc.y) - * \f] + * \f] * And the tool-tip will be located at \f$cl.z = cc.z + r_2*n.z - r_2\f$ - * + * * \subsubsection conefacettest Conical cutter facet test * Describe ConeCutter facet test here. - * + * * \subsection edgetest Edge test * Each test loops through all three edges of the triangle. The edge is defined by its startpoint * p1 and its endpoint p2. - * + * * It is easier to do the tests in a translated and rotated coordinate system where the - * cl-point is at (0,0) and the edge is rotated to be parallel with the X-axis. We call the + * cl-point is at (0,0) and the edge is rotated to be parallel with the X-axis. We call the * new endpoints of the edge p1u and p2u. These are found by noting that * \f[ * p1u_y = d * p2u_y = d - * \f] - * where d is the distance, in the XY-plane, from cl to a line through p1 and p2, - * i.e. \f$d = cl.xyDistanceToLine(p1, p2) \f$. We also define, in the XY-plane, + * \f] + * where d is the distance, in the XY-plane, from cl to a line through p1 and p2, + * i.e. \f$d = cl.xyDistanceToLine(p1, p2) \f$. We also define, in the XY-plane, * the closest point to cl on the line as: \f$ sc = cl.xyClosestPoint( p1, p2 ) \f$. - * + * * Now the x-coordinates of p1u and p2u are given by: * \f[ * p1u_x = (p1-sc).dot(v) * p2u_x = (p2-sc).dot(v) * \f] * where v is a normalized vector in the direction of the edge, or v=(p2-p1).xyNormalize() - * + * * The tests find a contact between the cutter and an infinite line which contains the * edge we are testing against. Once the contact cc-point is found we check whether this cc-point is * actually in the edge. - * + * * \subsubsection cyledge Cylindrical cutter edge test * In the XY-plane we want to find the intersection between an infinite line and a circle. * This is described e.g. here: see http://mathworld.wolfram.com/Circle-LineIntersection.html - * + * * \subsubsection balledge Spherical cutter edge test * \subsubsection bulledge Toroidal cutter edge test * \subsubsection coneedge Conical cutter edge test - * + * * \subsection optdc Optimizing drop-cutter * \subsubsection kdtree Using a kd-tree for finding triangles under the cutter - * - * - * + * + * + * * \section Z-slice - * An algorithm for 'slicing' an STL surface at a defined Z-coordinate. Produces waterline type paths. + * An algorithm for 'slicing' an STL surface at a defined Z-coordinate. Produces waterline type paths. * These contours can be used as a starting point for area-clearing algorithms in roughing operations. - * - * + * + * * \section cutsim Cutting Simulation * Describe cutting simulation here (octree etc). - * - * + * + * * \section References * \subsection Books * \li O'Rourke, Computational Geometry in C. * \li deBerg, Computational Geometry: Algorithms and Applications * \li Ghali, Introduction to Geometric Computing - * - * \subsection Papers - * \li Chuang2002 http://dx.doi.org/10.1007/PL00003965 "A Reverse Engineering Approach to Generating Interference-Free Tool - * Paths in Three-Axis Machining from Scanned Data of Physical Models" + * + * \subsection Papers + * \li Chuang2002 http://dx.doi.org/10.1007/PL00003965 "A Reverse Engineering Approach to Generating Interference-Free + * Tool Paths in Three-Axis Machining from Scanned Data of Physical Models" * - this paper contains the basics of drop-cutter - * \li Hwang1998 http://dx.doi.org/10.1016/S0010-4485(98)00021-9 - * - DropCutter for flat, filleted and ball-nose cutters. Edge test with iterative solution. - * \li Yau2004 http://dx.doi.org/10.1080/00207540410001671651 - * - DropCutter for a general APT-style cutter. This includes cutters with pointed ends and tapered cutters. + * \li Hwang1998 http://dx.doi.org/10.1016/S0010-4485(98)00021-9 + * - DropCutter for flat, filleted and ball-nose cutters. Edge test with iterative solution. + * \li Yau2004 http://dx.doi.org/10.1080/00207540410001671651 + * - DropCutter for a general APT-style cutter. This includes cutters with pointed ends and tapered cutters. * - kd-tree for triangle search - * \li Chuang2005 http://dx.doi.org/10.1016/j.cad.2004.10.005 - * - presents a Push-cutter idea for calculating z-level (waterline) paths. - * -*/ - - - - - + * \li Chuang2005 http://dx.doi.org/10.1016/j.cad.2004.10.005 + * - presents a Push-cutter idea for calculating z-level (waterline) paths. + * + */ diff --git a/src/nodejslib/adaptivepathdropcutter_js.cpp b/src/nodejslib/adaptivepathdropcutter_js.cpp index 649cca43..18443163 100644 --- a/src/nodejslib/adaptivepathdropcutter_js.cpp +++ b/src/nodejslib/adaptivepathdropcutter_js.cpp @@ -1,47 +1,44 @@ #include "adaptivepathdropcutter_js.hpp" -#include "point.hpp" -#include "clpoint.hpp" -#include "path_js.hpp" -#include "stlsurf_js.hpp" -#include "cylcutter_js.hpp" #include "ballcutter_js.hpp" #include "bullcutter_js.hpp" +#include "clpoint.hpp" #include "conecutter_js.hpp" +#include "cylcutter_js.hpp" +#include "path_js.hpp" +#include "point.hpp" +#include "stlsurf_js.hpp" Napi::FunctionReference AdaptivePathDropCutterJS::constructor; -void AdaptivePathDropCutterJS::Init(Napi::Env env, Napi::Object exports) -{ +void AdaptivePathDropCutterJS::Init(Napi::Env env, Napi::Object exports) { Napi::HandleScope scope(env); - Napi::Function func = DefineClass(env, "AdaptivePathDropCutter", { - InstanceMethod("setSTL", &AdaptivePathDropCutterJS::setSTL), - InstanceMethod("setPath", &AdaptivePathDropCutterJS::setPath), - InstanceMethod("setCylCutter", &AdaptivePathDropCutterJS::setCylCutter), - InstanceMethod("setBallCutter", &AdaptivePathDropCutterJS::setBallCutter), - InstanceMethod("setBullCutter", &AdaptivePathDropCutterJS::setBullCutter), - InstanceMethod("setConeCutter", &AdaptivePathDropCutterJS::setConeCutter), - InstanceMethod("setSampling", &AdaptivePathDropCutterJS::setSampling), - InstanceMethod("setMinSampling", &AdaptivePathDropCutterJS::setMinSampling), - InstanceMethod("setZ", &AdaptivePathDropCutterJS::setZ), - InstanceMethod("getCLPoints", &AdaptivePathDropCutterJS::getCLPoints), - InstanceMethod("run", &AdaptivePathDropCutterJS::run) - }); + Napi::Function func = DefineClass(env, "AdaptivePathDropCutter", + {InstanceMethod("setSTL", &AdaptivePathDropCutterJS::setSTL), + InstanceMethod("setPath", &AdaptivePathDropCutterJS::setPath), + InstanceMethod("setCylCutter", &AdaptivePathDropCutterJS::setCylCutter), + InstanceMethod("setBallCutter", &AdaptivePathDropCutterJS::setBallCutter), + InstanceMethod("setBullCutter", &AdaptivePathDropCutterJS::setBullCutter), + InstanceMethod("setConeCutter", &AdaptivePathDropCutterJS::setConeCutter), + InstanceMethod("setSampling", &AdaptivePathDropCutterJS::setSampling), + InstanceMethod("setMinSampling", &AdaptivePathDropCutterJS::setMinSampling), + InstanceMethod("setZ", &AdaptivePathDropCutterJS::setZ), + InstanceMethod("getCLPoints", &AdaptivePathDropCutterJS::getCLPoints), + InstanceMethod("run", &AdaptivePathDropCutterJS::run)}); constructor = Napi::Persistent(func); constructor.SuppressDestruct(); exports.Set("AdaptivePathDropCutter", func); } -AdaptivePathDropCutterJS::AdaptivePathDropCutterJS(const Napi::CallbackInfo &info) : Napi::ObjectWrap(info) -{ +AdaptivePathDropCutterJS::AdaptivePathDropCutterJS(const Napi::CallbackInfo &info) + : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); this->actualClass_ = new ocl::AdaptivePathDropCutter(); } -void AdaptivePathDropCutterJS::setSTL(const Napi::CallbackInfo &info) -{ +void AdaptivePathDropCutterJS::setSTL(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); STLSurfJS *sjs = Napi::ObjectWrap::Unwrap(info[0].As()); @@ -49,8 +46,7 @@ void AdaptivePathDropCutterJS::setSTL(const Napi::CallbackInfo &info) this->actualClass_->setSTL(*surface); } -void AdaptivePathDropCutterJS::setPath(const Napi::CallbackInfo &info) -{ +void AdaptivePathDropCutterJS::setPath(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); PathJS *pjs = Napi::ObjectWrap::Unwrap(info[0].As()); @@ -58,8 +54,7 @@ void AdaptivePathDropCutterJS::setPath(const Napi::CallbackInfo &info) this->actualClass_->setPath(path); } -void AdaptivePathDropCutterJS::setCylCutter(const Napi::CallbackInfo &info) -{ +void AdaptivePathDropCutterJS::setCylCutter(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); CylCutterJS *cjs = Napi::ObjectWrap::Unwrap(info[0].As()); @@ -67,8 +62,7 @@ void AdaptivePathDropCutterJS::setCylCutter(const Napi::CallbackInfo &info) this->actualClass_->setCutter(cutter); } -void AdaptivePathDropCutterJS::setBallCutter(const Napi::CallbackInfo &info) -{ +void AdaptivePathDropCutterJS::setBallCutter(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); BallCutterJS *cjs = Napi::ObjectWrap::Unwrap(info[0].As()); @@ -76,8 +70,7 @@ void AdaptivePathDropCutterJS::setBallCutter(const Napi::CallbackInfo &info) this->actualClass_->setCutter(cutter); } -void AdaptivePathDropCutterJS::setBullCutter(const Napi::CallbackInfo &info) -{ +void AdaptivePathDropCutterJS::setBullCutter(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); BullCutterJS *cjs = Napi::ObjectWrap::Unwrap(info[0].As()); @@ -85,8 +78,7 @@ void AdaptivePathDropCutterJS::setBullCutter(const Napi::CallbackInfo &info) this->actualClass_->setCutter(cutter); } -void AdaptivePathDropCutterJS::setConeCutter(const Napi::CallbackInfo &info) -{ +void AdaptivePathDropCutterJS::setConeCutter(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); ConeCutterJS *cjs = Napi::ObjectWrap::Unwrap(info[0].As()); @@ -94,32 +86,28 @@ void AdaptivePathDropCutterJS::setConeCutter(const Napi::CallbackInfo &info) this->actualClass_->setCutter(cutter); } -void AdaptivePathDropCutterJS::setSampling(const Napi::CallbackInfo &info) -{ +void AdaptivePathDropCutterJS::setSampling(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); Napi::Number s = info[0].As(); this->actualClass_->setSampling(s.DoubleValue()); } -void AdaptivePathDropCutterJS::setMinSampling(const Napi::CallbackInfo &info) -{ +void AdaptivePathDropCutterJS::setMinSampling(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); Napi::Number s = info[0].As(); this->actualClass_->setMinSampling(s.DoubleValue()); } -void AdaptivePathDropCutterJS::setZ(const Napi::CallbackInfo &info) -{ +void AdaptivePathDropCutterJS::setZ(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); Napi::Number s = info[0].As(); this->actualClass_->setZ(s.DoubleValue()); } -Napi::Value AdaptivePathDropCutterJS::getCLPoints(const Napi::CallbackInfo &info) -{ +Napi::Value AdaptivePathDropCutterJS::getCLPoints(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); Napi::Array result = Napi::Array::New(env); @@ -129,8 +117,7 @@ Napi::Value AdaptivePathDropCutterJS::getCLPoints(const Napi::CallbackInfo &info int z = 2; int i = 0; // std::cout << points.size(); - for (auto & point : points) - { + for (auto &point : points) { Napi::Array pointArr = Napi::Array::New(env); pointArr.Set(x, Napi::Number::New(env, point.x)); pointArr.Set(y, Napi::Number::New(env, point.y)); @@ -141,8 +128,7 @@ Napi::Value AdaptivePathDropCutterJS::getCLPoints(const Napi::CallbackInfo &info return result; } -void AdaptivePathDropCutterJS::run(const Napi::CallbackInfo &info) -{ +void AdaptivePathDropCutterJS::run(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); this->actualClass_->run(); diff --git a/src/nodejslib/adaptivepathdropcutter_js.hpp b/src/nodejslib/adaptivepathdropcutter_js.hpp index e159daaa..bf275dc1 100644 --- a/src/nodejslib/adaptivepathdropcutter_js.hpp +++ b/src/nodejslib/adaptivepathdropcutter_js.hpp @@ -1,8 +1,7 @@ -#include #include "adaptivepathdropcutter.hpp" +#include -class AdaptivePathDropCutterJS : public Napi::ObjectWrap -{ +class AdaptivePathDropCutterJS : public Napi::ObjectWrap { public: static void Init(Napi::Env env, Napi::Object exports); AdaptivePathDropCutterJS(const Napi::CallbackInfo &info); @@ -17,6 +16,7 @@ class AdaptivePathDropCutterJS : public Napi::ObjectWrap(info) -{ +AdaptiveWaterlineJS::AdaptiveWaterlineJS(const Napi::CallbackInfo &info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); this->actualClass_ = new ocl::AdaptiveWaterline(); } -void AdaptiveWaterlineJS::setZ(const Napi::CallbackInfo &info) -{ +void AdaptiveWaterlineJS::setZ(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); Napi::Number z = info[0].As(); this->actualClass_->setZ(z.DoubleValue()); } -void AdaptiveWaterlineJS::setSTL(const Napi::CallbackInfo &info) -{ +void AdaptiveWaterlineJS::setSTL(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); STLSurfJS *sjs = Napi::ObjectWrap::Unwrap(info[0].As()); @@ -55,8 +49,7 @@ void AdaptiveWaterlineJS::setSTL(const Napi::CallbackInfo &info) this->actualClass_->setSTL(*surface); } -void AdaptiveWaterlineJS::setCylCutter(const Napi::CallbackInfo &info) -{ +void AdaptiveWaterlineJS::setCylCutter(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); CylCutterJS *cjs = Napi::ObjectWrap::Unwrap(info[0].As()); @@ -64,8 +57,7 @@ void AdaptiveWaterlineJS::setCylCutter(const Napi::CallbackInfo &info) this->actualClass_->setCutter(cutter); } -void AdaptiveWaterlineJS::setBallCutter(const Napi::CallbackInfo &info) -{ +void AdaptiveWaterlineJS::setBallCutter(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); BallCutterJS *cjs = Napi::ObjectWrap::Unwrap(info[0].As()); @@ -73,8 +65,7 @@ void AdaptiveWaterlineJS::setBallCutter(const Napi::CallbackInfo &info) this->actualClass_->setCutter(cutter); } -void AdaptiveWaterlineJS::setBullCutter(const Napi::CallbackInfo &info) -{ +void AdaptiveWaterlineJS::setBullCutter(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); BullCutterJS *cjs = Napi::ObjectWrap::Unwrap(info[0].As()); @@ -82,8 +73,7 @@ void AdaptiveWaterlineJS::setBullCutter(const Napi::CallbackInfo &info) this->actualClass_->setCutter(cutter); } -void AdaptiveWaterlineJS::setConeCutter(const Napi::CallbackInfo &info) -{ +void AdaptiveWaterlineJS::setConeCutter(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); ConeCutterJS *cjs = Napi::ObjectWrap::Unwrap(info[0].As()); @@ -91,31 +81,27 @@ void AdaptiveWaterlineJS::setConeCutter(const Napi::CallbackInfo &info) this->actualClass_->setCutter(cutter); } -void AdaptiveWaterlineJS::setSampling(const Napi::CallbackInfo &info) -{ +void AdaptiveWaterlineJS::setSampling(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); Napi::Number s = info[0].As(); this->actualClass_->setSampling(s.DoubleValue()); } -void AdaptiveWaterlineJS::setMinSampling(const Napi::CallbackInfo &info) -{ +void AdaptiveWaterlineJS::setMinSampling(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); Napi::Number s = info[0].As(); this->actualClass_->setMinSampling(s.DoubleValue()); } -void AdaptiveWaterlineJS::run(const Napi::CallbackInfo &info) -{ +void AdaptiveWaterlineJS::run(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); this->actualClass_->run(); } -Napi::Value AdaptiveWaterlineJS::getLoops(const Napi::CallbackInfo &info) -{ +Napi::Value AdaptiveWaterlineJS::getLoops(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); Napi::Array result = Napi::Array::New(env); @@ -124,12 +110,10 @@ Napi::Value AdaptiveWaterlineJS::getLoops(const Napi::CallbackInfo &info) int y = 1; int z = 2; int loopI = 0; - for (auto &loop : loops) - { + for (auto &loop : loops) { Napi::Array loopArr = Napi::Array::New(env); int pointI = 0; - for (auto &point : loop) - { + for (auto &point : loop) { Napi::Array pointArr = Napi::Array::New(env); pointArr.Set(x, Napi::Number::New(env, point.x)); pointArr.Set(y, Napi::Number::New(env, point.y)); diff --git a/src/nodejslib/adaptivewaterline_js.hpp b/src/nodejslib/adaptivewaterline_js.hpp index e6099fca..ab632468 100644 --- a/src/nodejslib/adaptivewaterline_js.hpp +++ b/src/nodejslib/adaptivewaterline_js.hpp @@ -1,8 +1,7 @@ -#include #include "adaptivewaterline.hpp" +#include -class AdaptiveWaterlineJS : public Napi::ObjectWrap -{ +class AdaptiveWaterlineJS : public Napi::ObjectWrap { public: static Napi::Object Init(Napi::Env env, Napi::Object exports); AdaptiveWaterlineJS(const Napi::CallbackInfo &info); diff --git a/src/nodejslib/ballcutter_js.cpp b/src/nodejslib/ballcutter_js.cpp index d51022ab..a5b4e3ed 100644 --- a/src/nodejslib/ballcutter_js.cpp +++ b/src/nodejslib/ballcutter_js.cpp @@ -2,13 +2,10 @@ Napi::FunctionReference BallCutterJS::constructor; -Napi::Object BallCutterJS::Init(Napi::Env env, Napi::Object exports) -{ +Napi::Object BallCutterJS::Init(Napi::Env env, Napi::Object exports) { Napi::HandleScope scope(env); - Napi::Function func = DefineClass(env, "BallCutter", { - InstanceMethod("str", &BallCutterJS::str) - }); + Napi::Function func = DefineClass(env, "BallCutter", {InstanceMethod("str", &BallCutterJS::str)}); constructor = Napi::Persistent(func); constructor.SuppressDestruct(); @@ -16,13 +13,11 @@ Napi::Object BallCutterJS::Init(Napi::Env env, Napi::Object exports) return exports; } -BallCutterJS::BallCutterJS(const Napi::CallbackInfo &info) : Napi::ObjectWrap(info) -{ +BallCutterJS::BallCutterJS(const Napi::CallbackInfo &info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); size_t length = info.Length(); - if (length != 2) - { + if (length != 2) { Napi::TypeError::New(env, "Provide 2 argument").ThrowAsJavaScriptException(); } Napi::Number d = info[0].As(); @@ -30,15 +25,13 @@ BallCutterJS::BallCutterJS(const Napi::CallbackInfo &info) : Napi::ObjectWrapactualClass_ = new ocl::BallCutter(d.DoubleValue(), l.DoubleValue()); } -Napi::Value BallCutterJS::str(const Napi::CallbackInfo &info) -{ +Napi::Value BallCutterJS::str(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); return Napi::String::New(env, this->actualClass_->str()); } -ocl::BallCutter *BallCutterJS::GetInternalInstance(const Napi::CallbackInfo &info) -{ +ocl::BallCutter *BallCutterJS::GetInternalInstance(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); return this->actualClass_; diff --git a/src/nodejslib/ballcutter_js.hpp b/src/nodejslib/ballcutter_js.hpp index a063d813..cf786ff2 100644 --- a/src/nodejslib/ballcutter_js.hpp +++ b/src/nodejslib/ballcutter_js.hpp @@ -1,8 +1,7 @@ -#include #include "ballcutter.hpp" +#include -class BallCutterJS : public Napi::ObjectWrap -{ +class BallCutterJS : public Napi::ObjectWrap { public: static Napi::Object Init(Napi::Env env, Napi::Object exports); BallCutterJS(const Napi::CallbackInfo &info); diff --git a/src/nodejslib/bbox_js.cpp b/src/nodejslib/bbox_js.cpp index 3baa5b18..2a692627 100644 --- a/src/nodejslib/bbox_js.cpp +++ b/src/nodejslib/bbox_js.cpp @@ -1,14 +1,12 @@ -#include "bbox.hpp" #include "bbox_js.hpp" +#include "bbox.hpp" Napi::FunctionReference BboxJS::constructor; -Napi::Object BboxJS::Init(Napi::Env env, Napi::Object exports) -{ +Napi::Object BboxJS::Init(Napi::Env env, Napi::Object exports) { Napi::HandleScope scope(env); - Napi::Function func = DefineClass(env, "Bbox", { - }); + Napi::Function func = DefineClass(env, "Bbox", {}); constructor = Napi::Persistent(func); constructor.SuppressDestruct(); @@ -16,15 +14,13 @@ Napi::Object BboxJS::Init(Napi::Env env, Napi::Object exports) return exports; } -BboxJS::BboxJS(const Napi::CallbackInfo &info) : Napi::ObjectWrap(info) -{ +BboxJS::BboxJS(const Napi::CallbackInfo &info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); this->actualClass_ = new ocl::Bbox(); } -ocl::Bbox* BboxJS::GetInternalInstance(const Napi::CallbackInfo &info) -{ +ocl::Bbox *BboxJS::GetInternalInstance(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); return this->actualClass_; diff --git a/src/nodejslib/bbox_js.hpp b/src/nodejslib/bbox_js.hpp index 55304d1a..51482cef 100644 --- a/src/nodejslib/bbox_js.hpp +++ b/src/nodejslib/bbox_js.hpp @@ -1,8 +1,7 @@ -#include #include "bbox.hpp" +#include -class BboxJS : public Napi::ObjectWrap -{ +class BboxJS : public Napi::ObjectWrap { public: static Napi::Object Init(Napi::Env env, Napi::Object exports); BboxJS(const Napi::CallbackInfo &info); diff --git a/src/nodejslib/bullcutter_js.cpp b/src/nodejslib/bullcutter_js.cpp index 2dbc12a7..02cc4a37 100644 --- a/src/nodejslib/bullcutter_js.cpp +++ b/src/nodejslib/bullcutter_js.cpp @@ -2,13 +2,10 @@ Napi::FunctionReference BullCutterJS::constructor; -Napi::Object BullCutterJS::Init(Napi::Env env, Napi::Object exports) -{ +Napi::Object BullCutterJS::Init(Napi::Env env, Napi::Object exports) { Napi::HandleScope scope(env); - Napi::Function func = DefineClass(env, "BullCutter", { - InstanceMethod("str", &BullCutterJS::str) - }); + Napi::Function func = DefineClass(env, "BullCutter", {InstanceMethod("str", &BullCutterJS::str)}); constructor = Napi::Persistent(func); constructor.SuppressDestruct(); @@ -16,13 +13,11 @@ Napi::Object BullCutterJS::Init(Napi::Env env, Napi::Object exports) return exports; } -BullCutterJS::BullCutterJS(const Napi::CallbackInfo &info) : Napi::ObjectWrap(info) -{ +BullCutterJS::BullCutterJS(const Napi::CallbackInfo &info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); size_t length = info.Length(); - if (length != 3) - { + if (length != 3) { Napi::TypeError::New(env, "Provide 3 argument").ThrowAsJavaScriptException(); } Napi::Number d = info[0].As(); @@ -31,15 +26,13 @@ BullCutterJS::BullCutterJS(const Napi::CallbackInfo &info) : Napi::ObjectWrapactualClass_ = new ocl::BullCutter(d.DoubleValue(), r.DoubleValue(), l.DoubleValue()); } -Napi::Value BullCutterJS::str(const Napi::CallbackInfo &info) -{ +Napi::Value BullCutterJS::str(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); return Napi::String::New(env, this->actualClass_->str()); } -ocl::BullCutter *BullCutterJS::GetInternalInstance(const Napi::CallbackInfo &info) -{ +ocl::BullCutter *BullCutterJS::GetInternalInstance(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); return this->actualClass_; diff --git a/src/nodejslib/bullcutter_js.hpp b/src/nodejslib/bullcutter_js.hpp index 09da2d0f..c62208ad 100644 --- a/src/nodejslib/bullcutter_js.hpp +++ b/src/nodejslib/bullcutter_js.hpp @@ -1,8 +1,7 @@ -#include #include "bullcutter.hpp" +#include -class BullCutterJS : public Napi::ObjectWrap -{ +class BullCutterJS : public Napi::ObjectWrap { public: static Napi::Object Init(Napi::Env env, Napi::Object exports); BullCutterJS(const Napi::CallbackInfo &info); diff --git a/src/nodejslib/conecutter_js.cpp b/src/nodejslib/conecutter_js.cpp index 11216ee0..56bf8bfb 100644 --- a/src/nodejslib/conecutter_js.cpp +++ b/src/nodejslib/conecutter_js.cpp @@ -2,13 +2,10 @@ Napi::FunctionReference ConeCutterJS::constructor; -Napi::Object ConeCutterJS::Init(Napi::Env env, Napi::Object exports) -{ +Napi::Object ConeCutterJS::Init(Napi::Env env, Napi::Object exports) { Napi::HandleScope scope(env); - Napi::Function func = DefineClass(env, "ConeCutter", { - InstanceMethod("str", &ConeCutterJS::str) - }); + Napi::Function func = DefineClass(env, "ConeCutter", {InstanceMethod("str", &ConeCutterJS::str)}); constructor = Napi::Persistent(func); constructor.SuppressDestruct(); @@ -16,13 +13,11 @@ Napi::Object ConeCutterJS::Init(Napi::Env env, Napi::Object exports) return exports; } -ConeCutterJS::ConeCutterJS(const Napi::CallbackInfo &info) : Napi::ObjectWrap(info) -{ +ConeCutterJS::ConeCutterJS(const Napi::CallbackInfo &info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); size_t length = info.Length(); - if (length != 3) - { + if (length != 3) { Napi::TypeError::New(env, "Provide 3 argument").ThrowAsJavaScriptException(); } Napi::Number d = info[0].As(); @@ -31,15 +26,13 @@ ConeCutterJS::ConeCutterJS(const Napi::CallbackInfo &info) : Napi::ObjectWrapactualClass_ = new ocl::ConeCutter(d.DoubleValue(), a.DoubleValue(), l.DoubleValue()); } -Napi::Value ConeCutterJS::str(const Napi::CallbackInfo &info) -{ +Napi::Value ConeCutterJS::str(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); return Napi::String::New(env, this->actualClass_->str()); } -ocl::ConeCutter *ConeCutterJS::GetInternalInstance(const Napi::CallbackInfo &info) -{ +ocl::ConeCutter *ConeCutterJS::GetInternalInstance(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); return this->actualClass_; diff --git a/src/nodejslib/conecutter_js.hpp b/src/nodejslib/conecutter_js.hpp index 441c563a..492058fe 100644 --- a/src/nodejslib/conecutter_js.hpp +++ b/src/nodejslib/conecutter_js.hpp @@ -1,8 +1,7 @@ -#include #include "conecutter.hpp" +#include -class ConeCutterJS : public Napi::ObjectWrap -{ +class ConeCutterJS : public Napi::ObjectWrap { public: static Napi::Object Init(Napi::Env env, Napi::Object exports); ConeCutterJS(const Napi::CallbackInfo &info); diff --git a/src/nodejslib/cylcutter_js.cpp b/src/nodejslib/cylcutter_js.cpp index f49d77cf..41c54bcd 100644 --- a/src/nodejslib/cylcutter_js.cpp +++ b/src/nodejslib/cylcutter_js.cpp @@ -1,15 +1,12 @@ -#include "cylcutter.hpp" #include "cylcutter_js.hpp" +#include "cylcutter.hpp" Napi::FunctionReference CylCutterJS::constructor; -Napi::Object CylCutterJS::Init(Napi::Env env, Napi::Object exports) -{ +Napi::Object CylCutterJS::Init(Napi::Env env, Napi::Object exports) { Napi::HandleScope scope(env); - Napi::Function func = DefineClass(env, "CylCutter", { - InstanceMethod("str", &CylCutterJS::str) - }); + Napi::Function func = DefineClass(env, "CylCutter", {InstanceMethod("str", &CylCutterJS::str)}); constructor = Napi::Persistent(func); constructor.SuppressDestruct(); @@ -17,13 +14,11 @@ Napi::Object CylCutterJS::Init(Napi::Env env, Napi::Object exports) return exports; } -CylCutterJS::CylCutterJS(const Napi::CallbackInfo &info) : Napi::ObjectWrap(info) -{ +CylCutterJS::CylCutterJS(const Napi::CallbackInfo &info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); size_t length = info.Length(); - if (length != 2) - { + if (length != 2) { Napi::TypeError::New(env, "Provide 2 argument").ThrowAsJavaScriptException(); } Napi::Number d = info[0].As(); @@ -31,15 +26,13 @@ CylCutterJS::CylCutterJS(const Napi::CallbackInfo &info) : Napi::ObjectWrapactualClass_ = new ocl::CylCutter(d.DoubleValue(), l.DoubleValue()); } -Napi::Value CylCutterJS::str(const Napi::CallbackInfo &info) -{ +Napi::Value CylCutterJS::str(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); return Napi::String::New(env, this->actualClass_->str()); } -ocl::CylCutter *CylCutterJS::GetInternalInstance(const Napi::CallbackInfo &info) -{ +ocl::CylCutter *CylCutterJS::GetInternalInstance(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); return this->actualClass_; diff --git a/src/nodejslib/cylcutter_js.hpp b/src/nodejslib/cylcutter_js.hpp index ecb8bdd8..ea74fc09 100644 --- a/src/nodejslib/cylcutter_js.hpp +++ b/src/nodejslib/cylcutter_js.hpp @@ -1,8 +1,7 @@ -#include #include "cylcutter.hpp" +#include -class CylCutterJS : public Napi::ObjectWrap -{ +class CylCutterJS : public Napi::ObjectWrap { public: static Napi::Object Init(Napi::Env env, Napi::Object exports); CylCutterJS(const Napi::CallbackInfo &info); diff --git a/src/nodejslib/line_js.cpp b/src/nodejslib/line_js.cpp index d52e06f1..7f86e5e8 100644 --- a/src/nodejslib/line_js.cpp +++ b/src/nodejslib/line_js.cpp @@ -1,41 +1,38 @@ -#include "line.hpp" #include "line_js.hpp" +#include "line.hpp" #include "point_js.hpp" Napi::FunctionReference LineJS::constructor; Napi::Object LineJS::Init(Napi::Env env, Napi::Object exports) { - Napi::HandleScope scope(env); + Napi::HandleScope scope(env); - Napi::Function func = DefineClass(env, "Line", { - }); - constructor = Napi::Persistent(func); - constructor.SuppressDestruct(); + Napi::Function func = DefineClass(env, "Line", {}); + constructor = Napi::Persistent(func); + constructor.SuppressDestruct(); - exports.Set("Line", func); - return exports; + exports.Set("Line", func); + return exports; } -LineJS::LineJS(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { - Napi::Env env = info.Env(); - Napi::HandleScope scope(env); +LineJS::LineJS(const Napi::CallbackInfo &info) : Napi::ObjectWrap(info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); - size_t length = info.Length(); - if (length == 1) { - Napi::TypeError::New(env, "Provide at least 2 arguments").ThrowAsJavaScriptException(); - } - else if (length == 2) - { - PointJS* p1in = Napi::ObjectWrap::Unwrap(info[0].As()); - PointJS* p2in = Napi::ObjectWrap::Unwrap(info[1].As()); - ocl::Point* p1 = p1in->GetInternalInstance(info); - ocl::Point* p2 = p2in->GetInternalInstance(info); - actualClass_ = new ocl::Line(*p1, *p2); - } + size_t length = info.Length(); + if (length == 1) { + Napi::TypeError::New(env, "Provide at least 2 arguments").ThrowAsJavaScriptException(); + } else if (length == 2) { + PointJS *p1in = Napi::ObjectWrap::Unwrap(info[0].As()); + PointJS *p2in = Napi::ObjectWrap::Unwrap(info[1].As()); + ocl::Point *p1 = p1in->GetInternalInstance(info); + ocl::Point *p2 = p2in->GetInternalInstance(info); + actualClass_ = new ocl::Line(*p1, *p2); + } } -ocl::Line* LineJS::GetInternalInstance(const Napi::CallbackInfo& info) { - Napi::Env env = info.Env(); - Napi::HandleScope scope(env); - return this->actualClass_; +ocl::Line *LineJS::GetInternalInstance(const Napi::CallbackInfo &info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + return this->actualClass_; } \ No newline at end of file diff --git a/src/nodejslib/line_js.hpp b/src/nodejslib/line_js.hpp index 54a30b0b..51e4d39f 100644 --- a/src/nodejslib/line_js.hpp +++ b/src/nodejslib/line_js.hpp @@ -1,13 +1,14 @@ -#include #include "line.hpp" +#include class LineJS : public Napi::ObjectWrap { - public: - static Napi::Object Init(Napi::Env env, Napi::Object exports); // Init function for setting the export key to JS - LineJS(const Napi::CallbackInfo& info); // Constructor to initialise - ocl::Line *GetInternalInstance(const Napi::CallbackInfo &info); + public: + static Napi::Object Init(Napi::Env env, Napi::Object exports); // Init function for setting the export key to JS + LineJS(const Napi::CallbackInfo &info); // Constructor to initialise + ocl::Line *GetInternalInstance(const Napi::CallbackInfo &info); -private: - static Napi::FunctionReference constructor; //reference to store the class definition that needs to be exported to JS - ocl::Line *actualClass_; // Internal instance of line used to perform actual operations. + private: + static Napi::FunctionReference + constructor; // reference to store the class definition that needs to be exported to JS + ocl::Line *actualClass_; // Internal instance of line used to perform actual operations. }; \ No newline at end of file diff --git a/src/nodejslib/nodejslib.cpp b/src/nodejslib/nodejslib.cpp index 2101530a..07be1e84 100644 --- a/src/nodejslib/nodejslib.cpp +++ b/src/nodejslib/nodejslib.cpp @@ -1,46 +1,46 @@ #include -#include "point_js.hpp" -#include "triangle_js.hpp" #include "bbox_js.hpp" -#include "path_js.hpp" #include "line_js.hpp" +#include "path_js.hpp" +#include "point_js.hpp" +#include "triangle_js.hpp" -#include "stlsurf_js.hpp" #include "stlreader_js.hpp" +#include "stlsurf_js.hpp" -#include "waterline_js.hpp" -#include "pathdropcutter_js.hpp" #include "adaptivepathdropcutter_js.hpp" #include "adaptivewaterline_js.hpp" +#include "pathdropcutter_js.hpp" +#include "waterline_js.hpp" -#include "cylcutter_js.hpp" #include "ballcutter_js.hpp" #include "bullcutter_js.hpp" #include "conecutter_js.hpp" +#include "cylcutter_js.hpp" using namespace Napi; Napi::Object InitAll(Napi::Env env, Napi::Object exports) { - PointJS::Init(env, exports); - TriangleJS::Init(env, exports); - BboxJS::Init(env, exports); - PathJS::Init(env, exports); - LineJS::Init(env, exports); - - WaterlineJS::Init(env, exports); - PathDropCutterJS::Init(env, exports); - AdaptivePathDropCutterJS::Init(env, exports); - AdaptiveWaterlineJS::Init(env, exports); - - STLSurfJS::Init(env, exports); - STLReaderJS::Init(env, exports); - - CylCutterJS::Init(env, exports); - BallCutterJS::Init(env, exports); - BullCutterJS::Init(env, exports); - ConeCutterJS::Init(env, exports); - return exports; + PointJS::Init(env, exports); + TriangleJS::Init(env, exports); + BboxJS::Init(env, exports); + PathJS::Init(env, exports); + LineJS::Init(env, exports); + + WaterlineJS::Init(env, exports); + PathDropCutterJS::Init(env, exports); + AdaptivePathDropCutterJS::Init(env, exports); + AdaptiveWaterlineJS::Init(env, exports); + + STLSurfJS::Init(env, exports); + STLReaderJS::Init(env, exports); + + CylCutterJS::Init(env, exports); + BallCutterJS::Init(env, exports); + BullCutterJS::Init(env, exports); + ConeCutterJS::Init(env, exports); + return exports; } NODE_API_MODULE(opencamlib, InitAll) \ No newline at end of file diff --git a/src/nodejslib/path_js.cpp b/src/nodejslib/path_js.cpp index 803f3541..d2d5a906 100644 --- a/src/nodejslib/path_js.cpp +++ b/src/nodejslib/path_js.cpp @@ -1,43 +1,43 @@ -#include "path.hpp" #include "path_js.hpp" #include "line_js.hpp" +#include "path.hpp" Napi::FunctionReference PathJS::constructor; Napi::Object PathJS::Init(Napi::Env env, Napi::Object exports) { - Napi::HandleScope scope(env); + Napi::HandleScope scope(env); - Napi::Function func = DefineClass(env, "Path", { - InstanceMethod("append", &PathJS::append), - }); - constructor = Napi::Persistent(func); - constructor.SuppressDestruct(); + Napi::Function func = DefineClass(env, "Path", + { + InstanceMethod("append", &PathJS::append), + }); + constructor = Napi::Persistent(func); + constructor.SuppressDestruct(); - exports.Set("Path", func); - return exports; + exports.Set("Path", func); + return exports; } -PathJS::PathJS(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { - Napi::Env env = info.Env(); - Napi::HandleScope scope(env); +PathJS::PathJS(const Napi::CallbackInfo &info) : Napi::ObjectWrap(info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); - this->actualClass_ = new ocl::Path(); + this->actualClass_ = new ocl::Path(); } -ocl::Path *PathJS::GetInternalInstance(const Napi::CallbackInfo &info) -{ - Napi::Env env = info.Env(); - Napi::HandleScope scope(env); - return this->actualClass_; +ocl::Path *PathJS::GetInternalInstance(const Napi::CallbackInfo &info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + return this->actualClass_; } -void PathJS::append(const Napi::CallbackInfo& info) { - Napi::Env env = info.Env(); - Napi::HandleScope scope(env); - if (info.Length() != 1) { - Napi::TypeError::New(env, "Argument expected").ThrowAsJavaScriptException(); - } - LineJS* ljs = Napi::ObjectWrap::Unwrap(info[0].As()); - ocl::Line* ocll = ljs->GetInternalInstance(info); - this->actualClass_->append(*ocll); +void PathJS::append(const Napi::CallbackInfo &info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + if (info.Length() != 1) { + Napi::TypeError::New(env, "Argument expected").ThrowAsJavaScriptException(); + } + LineJS *ljs = Napi::ObjectWrap::Unwrap(info[0].As()); + ocl::Line *ocll = ljs->GetInternalInstance(info); + this->actualClass_->append(*ocll); } \ No newline at end of file diff --git a/src/nodejslib/path_js.hpp b/src/nodejslib/path_js.hpp index 5cb8df79..4e1b6835 100644 --- a/src/nodejslib/path_js.hpp +++ b/src/nodejslib/path_js.hpp @@ -1,14 +1,15 @@ -#include #include "path.hpp" +#include class PathJS : public Napi::ObjectWrap { - public: - static Napi::Object Init(Napi::Env env, Napi::Object exports); // Init function for setting the export key to JS - PathJS(const Napi::CallbackInfo& info); // Constructor to initialise - ocl::Path *GetInternalInstance(const Napi::CallbackInfo &info); + public: + static Napi::Object Init(Napi::Env env, Napi::Object exports); // Init function for setting the export key to JS + PathJS(const Napi::CallbackInfo &info); // Constructor to initialise + ocl::Path *GetInternalInstance(const Napi::CallbackInfo &info); -private: - static Napi::FunctionReference constructor; //reference to store the class definition that needs to be exported to JS - void append(const Napi::CallbackInfo& info); // wrapped add function - ocl::Path *actualClass_; // Internal instance of path used to perform actual operations. + private: + static Napi::FunctionReference + constructor; // reference to store the class definition that needs to be exported to JS + void append(const Napi::CallbackInfo &info); // wrapped add function + ocl::Path *actualClass_; // Internal instance of path used to perform actual operations. }; \ No newline at end of file diff --git a/src/nodejslib/pathdropcutter_js.cpp b/src/nodejslib/pathdropcutter_js.cpp index 5fef09ae..ca096be0 100644 --- a/src/nodejslib/pathdropcutter_js.cpp +++ b/src/nodejslib/pathdropcutter_js.cpp @@ -1,46 +1,41 @@ #include "pathdropcutter_js.hpp" -#include "point.hpp" -#include "clpoint.hpp" -#include "path_js.hpp" -#include "stlsurf_js.hpp" -#include "cylcutter_js.hpp" #include "ballcutter_js.hpp" #include "bullcutter_js.hpp" +#include "clpoint.hpp" #include "conecutter_js.hpp" +#include "cylcutter_js.hpp" +#include "path_js.hpp" +#include "point.hpp" +#include "stlsurf_js.hpp" Napi::FunctionReference PathDropCutterJS::constructor; -void PathDropCutterJS::Init(Napi::Env env, Napi::Object exports) -{ +void PathDropCutterJS::Init(Napi::Env env, Napi::Object exports) { Napi::HandleScope scope(env); - Napi::Function func = DefineClass(env, "PathDropCutter", { - InstanceMethod("setSTL", &PathDropCutterJS::setSTL), - InstanceMethod("setPath", &PathDropCutterJS::setPath), - InstanceMethod("setCylCutter", &PathDropCutterJS::setCylCutter), - InstanceMethod("setBallCutter", &PathDropCutterJS::setBallCutter), - InstanceMethod("setBullCutter", &PathDropCutterJS::setBullCutter), - InstanceMethod("setConeCutter", &PathDropCutterJS::setConeCutter), - InstanceMethod("setSampling", &PathDropCutterJS::setSampling), - InstanceMethod("getCLPoints", &PathDropCutterJS::getCLPoints), - InstanceMethod("setZ", &PathDropCutterJS::setZ), - InstanceMethod("run", &PathDropCutterJS::run) - }); + Napi::Function func = DefineClass( + env, "PathDropCutter", + {InstanceMethod("setSTL", &PathDropCutterJS::setSTL), InstanceMethod("setPath", &PathDropCutterJS::setPath), + InstanceMethod("setCylCutter", &PathDropCutterJS::setCylCutter), + InstanceMethod("setBallCutter", &PathDropCutterJS::setBallCutter), + InstanceMethod("setBullCutter", &PathDropCutterJS::setBullCutter), + InstanceMethod("setConeCutter", &PathDropCutterJS::setConeCutter), + InstanceMethod("setSampling", &PathDropCutterJS::setSampling), + InstanceMethod("getCLPoints", &PathDropCutterJS::getCLPoints), InstanceMethod("setZ", &PathDropCutterJS::setZ), + InstanceMethod("run", &PathDropCutterJS::run)}); constructor = Napi::Persistent(func); constructor.SuppressDestruct(); exports.Set("PathDropCutter", func); } -PathDropCutterJS::PathDropCutterJS(const Napi::CallbackInfo &info) : Napi::ObjectWrap(info) -{ +PathDropCutterJS::PathDropCutterJS(const Napi::CallbackInfo &info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); this->actualClass_ = new ocl::PathDropCutter(); } -void PathDropCutterJS::setSTL(const Napi::CallbackInfo &info) -{ +void PathDropCutterJS::setSTL(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); STLSurfJS *sjs = Napi::ObjectWrap::Unwrap(info[0].As()); @@ -48,8 +43,7 @@ void PathDropCutterJS::setSTL(const Napi::CallbackInfo &info) this->actualClass_->setSTL(*surface); } -void PathDropCutterJS::setPath(const Napi::CallbackInfo &info) -{ +void PathDropCutterJS::setPath(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); PathJS *pjs = Napi::ObjectWrap::Unwrap(info[0].As()); @@ -57,8 +51,7 @@ void PathDropCutterJS::setPath(const Napi::CallbackInfo &info) this->actualClass_->setPath(path); } -void PathDropCutterJS::setCylCutter(const Napi::CallbackInfo &info) -{ +void PathDropCutterJS::setCylCutter(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); CylCutterJS *cjs = Napi::ObjectWrap::Unwrap(info[0].As()); @@ -66,8 +59,7 @@ void PathDropCutterJS::setCylCutter(const Napi::CallbackInfo &info) this->actualClass_->setCutter(cutter); } -void PathDropCutterJS::setBallCutter(const Napi::CallbackInfo &info) -{ +void PathDropCutterJS::setBallCutter(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); BallCutterJS *cjs = Napi::ObjectWrap::Unwrap(info[0].As()); @@ -75,8 +67,7 @@ void PathDropCutterJS::setBallCutter(const Napi::CallbackInfo &info) this->actualClass_->setCutter(cutter); } -void PathDropCutterJS::setBullCutter(const Napi::CallbackInfo &info) -{ +void PathDropCutterJS::setBullCutter(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); BullCutterJS *cjs = Napi::ObjectWrap::Unwrap(info[0].As()); @@ -84,8 +75,7 @@ void PathDropCutterJS::setBullCutter(const Napi::CallbackInfo &info) this->actualClass_->setCutter(cutter); } -void PathDropCutterJS::setConeCutter(const Napi::CallbackInfo &info) -{ +void PathDropCutterJS::setConeCutter(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); ConeCutterJS *cjs = Napi::ObjectWrap::Unwrap(info[0].As()); @@ -93,24 +83,21 @@ void PathDropCutterJS::setConeCutter(const Napi::CallbackInfo &info) this->actualClass_->setCutter(cutter); } -void PathDropCutterJS::setSampling(const Napi::CallbackInfo &info) -{ +void PathDropCutterJS::setSampling(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); Napi::Number s = info[0].As(); this->actualClass_->setSampling(s.DoubleValue()); } -void PathDropCutterJS::setZ(const Napi::CallbackInfo &info) -{ +void PathDropCutterJS::setZ(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); Napi::Number s = info[0].As(); this->actualClass_->setZ(s.DoubleValue()); } -Napi::Value PathDropCutterJS::getCLPoints(const Napi::CallbackInfo &info) -{ +Napi::Value PathDropCutterJS::getCLPoints(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); Napi::Array result = Napi::Array::New(env); @@ -119,8 +106,7 @@ Napi::Value PathDropCutterJS::getCLPoints(const Napi::CallbackInfo &info) int y = 1; int z = 2; int i = 0; - for (auto &point : points) - { + for (auto &point : points) { Napi::Array pointArr = Napi::Array::New(env); pointArr.Set(x, Napi::Number::New(env, point.x)); pointArr.Set(y, Napi::Number::New(env, point.y)); @@ -131,7 +117,4 @@ Napi::Value PathDropCutterJS::getCLPoints(const Napi::CallbackInfo &info) return result; } -void PathDropCutterJS::run(const Napi::CallbackInfo &info) -{ - this->actualClass_->run(); -} +void PathDropCutterJS::run(const Napi::CallbackInfo &info) { this->actualClass_->run(); } diff --git a/src/nodejslib/pathdropcutter_js.hpp b/src/nodejslib/pathdropcutter_js.hpp index 093c34dd..f06ded7b 100644 --- a/src/nodejslib/pathdropcutter_js.hpp +++ b/src/nodejslib/pathdropcutter_js.hpp @@ -1,8 +1,7 @@ -#include #include "pathdropcutter.hpp" +#include -class PathDropCutterJS : public Napi::ObjectWrap -{ +class PathDropCutterJS : public Napi::ObjectWrap { public: static void Init(Napi::Env env, Napi::Object exports); PathDropCutterJS(const Napi::CallbackInfo &info); diff --git a/src/nodejslib/point_js.cpp b/src/nodejslib/point_js.cpp index 0a1418ce..2b2180d8 100644 --- a/src/nodejslib/point_js.cpp +++ b/src/nodejslib/point_js.cpp @@ -1,98 +1,98 @@ -#include "point.hpp" #include "point_js.hpp" +#include "point.hpp" Napi::FunctionReference PointJS::constructor; Napi::Object PointJS::Init(Napi::Env env, Napi::Object exports) { - Napi::HandleScope scope(env); + Napi::HandleScope scope(env); - Napi::Function func = DefineClass(env, "Point", { - InstanceMethod("add", &PointJS::Add), - InstanceAccessor("x", &PointJS::GetX, &PointJS::SetX), - InstanceAccessor("y", &PointJS::GetY, &PointJS::SetY), - InstanceAccessor("z", &PointJS::GetZ, &PointJS::SetZ), - }); - constructor = Napi::Persistent(func); - constructor.SuppressDestruct(); + Napi::Function func = DefineClass(env, "Point", + { + InstanceMethod("add", &PointJS::Add), + InstanceAccessor("x", &PointJS::GetX, &PointJS::SetX), + InstanceAccessor("y", &PointJS::GetY, &PointJS::SetY), + InstanceAccessor("z", &PointJS::GetZ, &PointJS::SetZ), + }); + constructor = Napi::Persistent(func); + constructor.SuppressDestruct(); - exports.Set("Point", func); - return exports; + exports.Set("Point", func); + return exports; } -Napi::Value PointJS::GetX(const Napi::CallbackInfo& info) { - Napi::Env env = info.Env(); - Napi::HandleScope scope(env); - return Napi::Number::New(env, this->actualClass_->x); +Napi::Value PointJS::GetX(const Napi::CallbackInfo &info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + return Napi::Number::New(env, this->actualClass_->x); } -void PointJS::SetX(const Napi::CallbackInfo& info, const Napi::Value& value) { - Napi::Env env = info.Env(); - Napi::HandleScope scope(env); - Napi::Number x = info[0].As(); - this->actualClass_->x = x.DoubleValue(); +void PointJS::SetX(const Napi::CallbackInfo &info, const Napi::Value &value) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + Napi::Number x = info[0].As(); + this->actualClass_->x = x.DoubleValue(); } -Napi::Value PointJS::GetY(const Napi::CallbackInfo& info) { - Napi::Env env = info.Env(); - Napi::HandleScope scope(env); - return Napi::Number::New(env, this->actualClass_->y); +Napi::Value PointJS::GetY(const Napi::CallbackInfo &info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + return Napi::Number::New(env, this->actualClass_->y); } -void PointJS::SetY(const Napi::CallbackInfo& info, const Napi::Value& value) { - Napi::Env env = info.Env(); - Napi::HandleScope scope(env); - Napi::Number y = info[0].As(); - this->actualClass_->y = y.DoubleValue(); +void PointJS::SetY(const Napi::CallbackInfo &info, const Napi::Value &value) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + Napi::Number y = info[0].As(); + this->actualClass_->y = y.DoubleValue(); } -Napi::Value PointJS::GetZ(const Napi::CallbackInfo& info) { - Napi::Env env = info.Env(); - Napi::HandleScope scope(env); - return Napi::Number::New(env, this->actualClass_->z); +Napi::Value PointJS::GetZ(const Napi::CallbackInfo &info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + return Napi::Number::New(env, this->actualClass_->z); } -void PointJS::SetZ(const Napi::CallbackInfo& info, const Napi::Value& value) { - Napi::Env env = info.Env(); - Napi::HandleScope scope(env); - Napi::Number z = info[0].As(); - this->actualClass_->z = z.DoubleValue(); +void PointJS::SetZ(const Napi::CallbackInfo &info, const Napi::Value &value) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + Napi::Number z = info[0].As(); + this->actualClass_->z = z.DoubleValue(); } -PointJS::PointJS(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { - Napi::Env env = info.Env(); - Napi::HandleScope scope(env); +PointJS::PointJS(const Napi::CallbackInfo &info) : Napi::ObjectWrap(info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); - size_t length = static_cast(info.Length()); - if (length == 1) { - Napi::TypeError::New(env, "Provide at least 2 arguments").ThrowAsJavaScriptException(); - } - if (length == 2) { - Napi::Number x = info[0].As(); - Napi::Number y = info[1].As(); - this->actualClass_ = new ocl::Point(x.DoubleValue(), y.DoubleValue()); - } else if (length == 3) { - Napi::Number x = info[0].As(); - Napi::Number y = info[1].As(); - Napi::Number z = info[2].As(); - this->actualClass_ = new ocl::Point(x.DoubleValue(), y.DoubleValue(), z.DoubleValue()); - } + size_t length = static_cast(info.Length()); + if (length == 1) { + Napi::TypeError::New(env, "Provide at least 2 arguments").ThrowAsJavaScriptException(); + } + if (length == 2) { + Napi::Number x = info[0].As(); + Napi::Number y = info[1].As(); + this->actualClass_ = new ocl::Point(x.DoubleValue(), y.DoubleValue()); + } else if (length == 3) { + Napi::Number x = info[0].As(); + Napi::Number y = info[1].As(); + Napi::Number z = info[2].As(); + this->actualClass_ = new ocl::Point(x.DoubleValue(), y.DoubleValue(), z.DoubleValue()); + } } -ocl::Point *PointJS::GetInternalInstance(const Napi::CallbackInfo &info) -{ - Napi::Env env = info.Env(); - Napi::HandleScope scope(env); - return this->actualClass_; +ocl::Point *PointJS::GetInternalInstance(const Napi::CallbackInfo &info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + return this->actualClass_; } -void PointJS::Add(const Napi::CallbackInfo& info) { - Napi::Env env = info.Env(); - Napi::HandleScope scope(env); - if (info.Length() != 1) { - Napi::TypeError::New(env, "Argument expected").ThrowAsJavaScriptException(); - } - PointJS* pjs = Napi::ObjectWrap::Unwrap(info[0].As()); - ocl::Point* oclp = pjs->GetInternalInstance(info); - ocl::Point p = *oclp; - this->actualClass_->operator+=(ocl::Point(p.x, p.y, p.z)); +void PointJS::Add(const Napi::CallbackInfo &info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + if (info.Length() != 1) { + Napi::TypeError::New(env, "Argument expected").ThrowAsJavaScriptException(); + } + PointJS *pjs = Napi::ObjectWrap::Unwrap(info[0].As()); + ocl::Point *oclp = pjs->GetInternalInstance(info); + ocl::Point p = *oclp; + this->actualClass_->operator+=(ocl::Point(p.x, p.y, p.z)); } \ No newline at end of file diff --git a/src/nodejslib/point_js.hpp b/src/nodejslib/point_js.hpp index 1bcddfe6..0af8d18f 100644 --- a/src/nodejslib/point_js.hpp +++ b/src/nodejslib/point_js.hpp @@ -1,20 +1,21 @@ -#include #include "point.hpp" +#include class PointJS : public Napi::ObjectWrap { - public: - static Napi::Object Init(Napi::Env env, Napi::Object exports); // Init function for setting the export key to JS - PointJS(const Napi::CallbackInfo& info); // Constructor to initialise - ocl::Point *GetInternalInstance(const Napi::CallbackInfo &info); + public: + static Napi::Object Init(Napi::Env env, Napi::Object exports); // Init function for setting the export key to JS + PointJS(const Napi::CallbackInfo &info); // Constructor to initialise + ocl::Point *GetInternalInstance(const Napi::CallbackInfo &info); -private: - static Napi::FunctionReference constructor; //reference to store the class definition that needs to be exported to JS - Napi::Value GetX(const Napi::CallbackInfo& info); - void SetX(const Napi::CallbackInfo& info, const Napi::Value& value); - Napi::Value GetY(const Napi::CallbackInfo& info); - void SetY(const Napi::CallbackInfo& info, const Napi::Value& value); - Napi::Value GetZ(const Napi::CallbackInfo& info); - void SetZ(const Napi::CallbackInfo& info, const Napi::Value& value); - void Add(const Napi::CallbackInfo& info); // wrapped add function - ocl::Point *actualClass_; // Internal instance of point used to perform actual operations. + private: + static Napi::FunctionReference + constructor; // reference to store the class definition that needs to be exported to JS + Napi::Value GetX(const Napi::CallbackInfo &info); + void SetX(const Napi::CallbackInfo &info, const Napi::Value &value); + Napi::Value GetY(const Napi::CallbackInfo &info); + void SetY(const Napi::CallbackInfo &info, const Napi::Value &value); + Napi::Value GetZ(const Napi::CallbackInfo &info); + void SetZ(const Napi::CallbackInfo &info, const Napi::Value &value); + void Add(const Napi::CallbackInfo &info); // wrapped add function + ocl::Point *actualClass_; // Internal instance of point used to perform actual operations. }; \ No newline at end of file diff --git a/src/nodejslib/stlreader_js.cpp b/src/nodejslib/stlreader_js.cpp index 25fb795d..69a96d9b 100644 --- a/src/nodejslib/stlreader_js.cpp +++ b/src/nodejslib/stlreader_js.cpp @@ -1,17 +1,15 @@ -#include +#include "stlreader_js.hpp" #include "stlreader.hpp" #include "stlsurf.hpp" -#include "stlreader_js.hpp" #include "stlsurf_js.hpp" +#include Napi::FunctionReference STLReaderJS::constructor; -Napi::Object STLReaderJS::Init(Napi::Env env, Napi::Object exports) -{ +Napi::Object STLReaderJS::Init(Napi::Env env, Napi::Object exports) { Napi::HandleScope scope(env); - Napi::Function func = DefineClass(env, "STLReader", { - }); + Napi::Function func = DefineClass(env, "STLReader", {}); constructor = Napi::Persistent(func); constructor.SuppressDestruct(); @@ -19,13 +17,11 @@ Napi::Object STLReaderJS::Init(Napi::Env env, Napi::Object exports) return exports; } -STLReaderJS::STLReaderJS(const Napi::CallbackInfo &info) : Napi::ObjectWrap(info) -{ +STLReaderJS::STLReaderJS(const Napi::CallbackInfo &info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); size_t length = info.Length(); - if (length == 1) - { + if (length == 1) { Napi::TypeError::New(env, "Provide at least 2 arguments").ThrowAsJavaScriptException(); } Napi::String filepath = info[0].As(); diff --git a/src/nodejslib/stlreader_js.hpp b/src/nodejslib/stlreader_js.hpp index 9d04941b..c42608bc 100644 --- a/src/nodejslib/stlreader_js.hpp +++ b/src/nodejslib/stlreader_js.hpp @@ -1,8 +1,7 @@ -#include #include "stlreader.hpp" +#include -class STLReaderJS : public Napi::ObjectWrap -{ +class STLReaderJS : public Napi::ObjectWrap { public: static Napi::Object Init(Napi::Env env, Napi::Object exports); STLReaderJS(const Napi::CallbackInfo &info); diff --git a/src/nodejslib/stlsurf_js.cpp b/src/nodejslib/stlsurf_js.cpp index 6bc2c368..0ab90c29 100644 --- a/src/nodejslib/stlsurf_js.cpp +++ b/src/nodejslib/stlsurf_js.cpp @@ -1,18 +1,16 @@ +#include "stlsurf_js.hpp" +#include "stlsurf.hpp" #include "triangle.hpp" #include "triangle_js.hpp" -#include "stlsurf.hpp" -#include "stlsurf_js.hpp" Napi::FunctionReference STLSurfJS::constructor; -Napi::Object STLSurfJS::Init(Napi::Env env, Napi::Object exports) -{ +Napi::Object STLSurfJS::Init(Napi::Env env, Napi::Object exports) { Napi::HandleScope scope(env); - Napi::Function func = DefineClass(env, "STLSurf", { - InstanceMethod("addTriangle", &STLSurfJS::addTriangle), - InstanceMethod("getTriangles", &STLSurfJS::getTriangles) - }); + Napi::Function func = DefineClass(env, "STLSurf", + {InstanceMethod("addTriangle", &STLSurfJS::addTriangle), + InstanceMethod("getTriangles", &STLSurfJS::getTriangles)}); constructor = Napi::Persistent(func); constructor.SuppressDestruct(); @@ -20,26 +18,22 @@ Napi::Object STLSurfJS::Init(Napi::Env env, Napi::Object exports) return exports; } -STLSurfJS::STLSurfJS(const Napi::CallbackInfo &info) : Napi::ObjectWrap(info) -{ +STLSurfJS::STLSurfJS(const Napi::CallbackInfo &info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); this->actualClass_ = new ocl::STLSurf(); } -ocl::STLSurf *STLSurfJS::GetInternalInstance(const Napi::CallbackInfo &info) -{ +ocl::STLSurf *STLSurfJS::GetInternalInstance(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); return this->actualClass_; } -void STLSurfJS::addTriangle(const Napi::CallbackInfo &info) -{ +void STLSurfJS::addTriangle(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); - if (info.Length() != 1) - { + if (info.Length() != 1) { Napi::TypeError::New(env, "Argument expected").ThrowAsJavaScriptException(); } TriangleJS *tjs = Napi::ObjectWrap::Unwrap(info[0].As()); @@ -47,8 +41,7 @@ void STLSurfJS::addTriangle(const Napi::CallbackInfo &info) this->actualClass_->addTriangle(*oclt); } -Napi::Value STLSurfJS::getTriangles(const Napi::CallbackInfo &info) -{ +Napi::Value STLSurfJS::getTriangles(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); Napi::Array arr = Napi::Array::New(env); @@ -57,8 +50,7 @@ Napi::Value STLSurfJS::getTriangles(const Napi::CallbackInfo &info) int b = 1; int c = 2; std::list::iterator it; - for (it = this->actualClass_->tris.begin(); it != this->actualClass_->tris.end(); ++it) - { + for (it = this->actualClass_->tris.begin(); it != this->actualClass_->tris.end(); ++it) { Napi::Array points = Napi::Array::New(env); Napi::Array p1 = Napi::Array::New(env); p1.Set(a, Napi::Number::New(env, it->p[0].x)); diff --git a/src/nodejslib/stlsurf_js.hpp b/src/nodejslib/stlsurf_js.hpp index ae681791..2906abe8 100644 --- a/src/nodejslib/stlsurf_js.hpp +++ b/src/nodejslib/stlsurf_js.hpp @@ -1,14 +1,14 @@ -#include #include "stlsurf.hpp" +#include -class STLSurfJS : public Napi::ObjectWrap -{ +class STLSurfJS : public Napi::ObjectWrap { public: static Napi::Object Init(Napi::Env env, Napi::Object exports); STLSurfJS(const Napi::CallbackInfo &info); ocl::STLSurf *GetInternalInstance(const Napi::CallbackInfo &info); void addTriangle(const Napi::CallbackInfo &info); Napi::Value getTriangles(const Napi::CallbackInfo &info); + private: static Napi::FunctionReference constructor; ocl::STLSurf *actualClass_; diff --git a/src/nodejslib/triangle_js.cpp b/src/nodejslib/triangle_js.cpp index 4fb2b3c6..9273d6e6 100644 --- a/src/nodejslib/triangle_js.cpp +++ b/src/nodejslib/triangle_js.cpp @@ -1,11 +1,10 @@ -#include "triangle.hpp" #include "triangle_js.hpp" #include "point_js.hpp" +#include "triangle.hpp" Napi::FunctionReference TriangleJS::constructor; -Napi::Object TriangleJS::Init(Napi::Env env, Napi::Object exports) -{ +Napi::Object TriangleJS::Init(Napi::Env env, Napi::Object exports) { Napi::HandleScope scope(env); Napi::Function func = DefineClass(env, "Triangle", {}); @@ -16,17 +15,13 @@ Napi::Object TriangleJS::Init(Napi::Env env, Napi::Object exports) return exports; } -TriangleJS::TriangleJS(const Napi::CallbackInfo &info) : Napi::ObjectWrap(info) -{ +TriangleJS::TriangleJS(const Napi::CallbackInfo &info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); size_t length = info.Length(); - if (length == 0) - { + if (length == 0) { this->actualClass_ = new ocl::Triangle(); - } - else if (length == 3) - { + } else if (length == 3) { PointJS *p1js = Napi::ObjectWrap::Unwrap(info[0].As()); ocl::Point *p1 = p1js->GetInternalInstance(info); PointJS *p2js = Napi::ObjectWrap::Unwrap(info[1].As()); @@ -34,15 +29,12 @@ TriangleJS::TriangleJS(const Napi::CallbackInfo &info) : Napi::ObjectWrap::Unwrap(info[2].As()); ocl::Point *p3 = p3js->GetInternalInstance(info); this->actualClass_ = new ocl::Triangle(*p1, *p2, *p3); - } - else - { + } else { Napi::TypeError::New(env, "Provide at 3 or 0 arguments").ThrowAsJavaScriptException(); } } -ocl::Triangle *TriangleJS::GetInternalInstance(const Napi::CallbackInfo &info) -{ +ocl::Triangle *TriangleJS::GetInternalInstance(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); return this->actualClass_; diff --git a/src/nodejslib/triangle_js.hpp b/src/nodejslib/triangle_js.hpp index c7f4ed92..0bad6c38 100644 --- a/src/nodejslib/triangle_js.hpp +++ b/src/nodejslib/triangle_js.hpp @@ -1,8 +1,7 @@ -#include #include "triangle.hpp" +#include -class TriangleJS : public Napi::ObjectWrap -{ +class TriangleJS : public Napi::ObjectWrap { public: static Napi::Object Init(Napi::Env env, Napi::Object exports); TriangleJS(const Napi::CallbackInfo &info); diff --git a/src/nodejslib/waterline_js.cpp b/src/nodejslib/waterline_js.cpp index c4a246dc..d3302271 100644 --- a/src/nodejslib/waterline_js.cpp +++ b/src/nodejslib/waterline_js.cpp @@ -1,28 +1,25 @@ #include "waterline_js.hpp" -#include "stlsurf_js.hpp" -#include "point.hpp" -#include "cylcutter_js.hpp" #include "ballcutter_js.hpp" #include "bullcutter_js.hpp" #include "conecutter_js.hpp" +#include "cylcutter_js.hpp" +#include "point.hpp" +#include "stlsurf_js.hpp" Napi::FunctionReference WaterlineJS::constructor; -Napi::Object WaterlineJS::Init(Napi::Env env, Napi::Object exports) -{ +Napi::Object WaterlineJS::Init(Napi::Env env, Napi::Object exports) { Napi::HandleScope scope(env); - Napi::Function func = DefineClass(env, "Waterline", { - InstanceMethod("setZ", &WaterlineJS::setZ), - InstanceMethod("setSTL", &WaterlineJS::setSTL), - InstanceMethod("setCylCutter", &WaterlineJS::setCylCutter), - InstanceMethod("setBallCutter", &WaterlineJS::setBallCutter), - InstanceMethod("setBullCutter", &WaterlineJS::setBullCutter), - InstanceMethod("setConeCutter", &WaterlineJS::setConeCutter), - InstanceMethod("setSampling", &WaterlineJS::setSampling), - InstanceMethod("run", &WaterlineJS::run), - InstanceMethod("getLoops", &WaterlineJS::getLoops) - }); + Napi::Function func = + DefineClass(env, "Waterline", + {InstanceMethod("setZ", &WaterlineJS::setZ), InstanceMethod("setSTL", &WaterlineJS::setSTL), + InstanceMethod("setCylCutter", &WaterlineJS::setCylCutter), + InstanceMethod("setBallCutter", &WaterlineJS::setBallCutter), + InstanceMethod("setBullCutter", &WaterlineJS::setBullCutter), + InstanceMethod("setConeCutter", &WaterlineJS::setConeCutter), + InstanceMethod("setSampling", &WaterlineJS::setSampling), InstanceMethod("run", &WaterlineJS::run), + InstanceMethod("getLoops", &WaterlineJS::getLoops)}); constructor = Napi::Persistent(func); constructor.SuppressDestruct(); @@ -32,23 +29,20 @@ Napi::Object WaterlineJS::Init(Napi::Env env, Napi::Object exports) return exports; } -WaterlineJS::WaterlineJS(const Napi::CallbackInfo &info) : Napi::ObjectWrap(info) -{ +WaterlineJS::WaterlineJS(const Napi::CallbackInfo &info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); this->actualClass_ = new ocl::Waterline(); } -void WaterlineJS::setZ(const Napi::CallbackInfo &info) -{ +void WaterlineJS::setZ(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); Napi::Number z = info[0].As(); this->actualClass_->setZ(z.DoubleValue()); } -void WaterlineJS::setSTL(const Napi::CallbackInfo &info) -{ +void WaterlineJS::setSTL(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); STLSurfJS *sjs = Napi::ObjectWrap::Unwrap(info[0].As()); @@ -56,8 +50,7 @@ void WaterlineJS::setSTL(const Napi::CallbackInfo &info) this->actualClass_->setSTL(*surface); } -void WaterlineJS::setCylCutter(const Napi::CallbackInfo &info) -{ +void WaterlineJS::setCylCutter(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); CylCutterJS *cjs = Napi::ObjectWrap::Unwrap(info[0].As()); @@ -65,8 +58,7 @@ void WaterlineJS::setCylCutter(const Napi::CallbackInfo &info) this->actualClass_->setCutter(cutter); } -void WaterlineJS::setBallCutter(const Napi::CallbackInfo &info) -{ +void WaterlineJS::setBallCutter(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); BallCutterJS *cjs = Napi::ObjectWrap::Unwrap(info[0].As()); @@ -74,8 +66,7 @@ void WaterlineJS::setBallCutter(const Napi::CallbackInfo &info) this->actualClass_->setCutter(cutter); } -void WaterlineJS::setBullCutter(const Napi::CallbackInfo &info) -{ +void WaterlineJS::setBullCutter(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); BullCutterJS *cjs = Napi::ObjectWrap::Unwrap(info[0].As()); @@ -83,8 +74,7 @@ void WaterlineJS::setBullCutter(const Napi::CallbackInfo &info) this->actualClass_->setCutter(cutter); } -void WaterlineJS::setConeCutter(const Napi::CallbackInfo &info) -{ +void WaterlineJS::setConeCutter(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); ConeCutterJS *cjs = Napi::ObjectWrap::Unwrap(info[0].As()); @@ -92,23 +82,20 @@ void WaterlineJS::setConeCutter(const Napi::CallbackInfo &info) this->actualClass_->setCutter(cutter); } -void WaterlineJS::setSampling(const Napi::CallbackInfo &info) -{ +void WaterlineJS::setSampling(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); Napi::Number s = info[0].As(); this->actualClass_->setSampling(s.DoubleValue()); } -void WaterlineJS::run(const Napi::CallbackInfo &info) -{ +void WaterlineJS::run(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); this->actualClass_->run(); } -Napi::Value WaterlineJS::getLoops(const Napi::CallbackInfo &info) -{ +Napi::Value WaterlineJS::getLoops(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); Napi::Array result = Napi::Array::New(env); @@ -117,12 +104,10 @@ Napi::Value WaterlineJS::getLoops(const Napi::CallbackInfo &info) int y = 1; int z = 2; int loopI = 0; - for (auto & loop : loops) - { + for (auto &loop : loops) { Napi::Array loopArr = Napi::Array::New(env); int pointI = 0; - for (auto &point : loop) - { + for (auto &point : loop) { Napi::Array pointArr = Napi::Array::New(env); pointArr.Set(x, Napi::Number::New(env, point.x)); pointArr.Set(y, Napi::Number::New(env, point.y)); diff --git a/src/nodejslib/waterline_js.hpp b/src/nodejslib/waterline_js.hpp index fa9e7d44..ce4117af 100644 --- a/src/nodejslib/waterline_js.hpp +++ b/src/nodejslib/waterline_js.hpp @@ -1,9 +1,8 @@ -#include -#include "waterline.hpp" #include "stlsurf.hpp" +#include "waterline.hpp" +#include -class WaterlineJS : public Napi::ObjectWrap -{ +class WaterlineJS : public Napi::ObjectWrap { public: static Napi::Object Init(Napi::Env env, Napi::Object exports); WaterlineJS(const Napi::CallbackInfo &info); @@ -16,6 +15,7 @@ class WaterlineJS : public Napi::ObjectWrap void setSampling(const Napi::CallbackInfo &info); void run(const Napi::CallbackInfo &info); Napi::Value getLoops(const Napi::CallbackInfo &info); + private: static Napi::FunctionReference constructor; ocl::Waterline *actualClass_; diff --git a/src/ocl.cpp b/src/ocl.cpp index 31e4f8e5..8b0d6aed 100644 --- a/src/ocl.cpp +++ b/src/ocl.cpp @@ -25,18 +25,13 @@ #endif #include "version_string.hpp" -namespace ocl -{ - int max_threads() - { +namespace ocl { +int max_threads() { #ifdef _OPENMP return omp_get_max_threads(); #endif return 1; - } +} - std::string version() - { - return VERSION_STRING; - } -} \ No newline at end of file +std::string version() { return VERSION_STRING; } +} // namespace ocl \ No newline at end of file diff --git a/src/ocl.hpp b/src/ocl.hpp index 5cd6149b..6b443c3f 100644 --- a/src/ocl.hpp +++ b/src/ocl.hpp @@ -23,10 +23,9 @@ #include -namespace ocl -{ - int max_threads(); - std::string version(); -} +namespace ocl { +int max_threads(); +std::string version(); +} // namespace ocl #endif \ No newline at end of file diff --git a/src/pythonlib/adaptivepathdropcutter_py.hpp b/src/pythonlib/adaptivepathdropcutter_py.hpp index 06068f65..8c5e6e25 100644 --- a/src/pythonlib/adaptivepathdropcutter_py.hpp +++ b/src/pythonlib/adaptivepathdropcutter_py.hpp @@ -1,23 +1,23 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef ADAPTIVEPATHDROPCUTTER_PY_H #define ADAPTIVEPATHDROPCUTTER_PY_H @@ -25,26 +25,25 @@ #include "adaptivepathdropcutter.hpp" -namespace ocl -{ - +namespace ocl { + /// Python wrapper for PathDropCutter class AdaptivePathDropCutter_py : public AdaptivePathDropCutter { - public: - AdaptivePathDropCutter_py() : AdaptivePathDropCutter() {} - virtual ~AdaptivePathDropCutter_py() {} - /// return a list of CL-points to python - boost::python::list getCLPoints_py() { - //std::cout << " apdc_py::getCLPoints_py()..."; - boost::python::list plist; - BOOST_FOREACH(CLPoint p, clpoints) { - plist.append(p); - } - //std::cout << " DONE.\n"; - return plist; + public: + AdaptivePathDropCutter_py() : AdaptivePathDropCutter() {} + virtual ~AdaptivePathDropCutter_py() {} + /// return a list of CL-points to python + boost::python::list getCLPoints_py() { + // std::cout << " apdc_py::getCLPoints_py()..."; + boost::python::list plist; + BOOST_FOREACH (CLPoint p, clpoints) { + plist.append(p); } + // std::cout << " DONE.\n"; + return plist; + } }; -} // end namespace +} // namespace ocl #endif // end file adaptivepathdropcutter_py.h diff --git a/src/pythonlib/adaptivewaterline_py.hpp b/src/pythonlib/adaptivewaterline_py.hpp index fe95bca5..c4429dac 100644 --- a/src/pythonlib/adaptivewaterline_py.hpp +++ b/src/pythonlib/adaptivewaterline_py.hpp @@ -1,76 +1,73 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef ADAPTIVEWATERLINE_PY_H #define ADAPTIVEWATERLINE_PY_H #include "adaptivewaterline.hpp" #include "fiber_py.hpp" -namespace ocl -{ +namespace ocl { /// \brief python wrapper for AdaptiveWaterline class AdaptiveWaterline_py : public AdaptiveWaterline { - public: - AdaptiveWaterline_py() : AdaptiveWaterline() {} - ~AdaptiveWaterline_py() { - std::cout << "~AdaptiveWaterline_py()\n"; - } - - /// return loop as a list of lists to python - boost::python::list py_getLoops() const { - boost::python::list loop_list; - BOOST_FOREACH( std::vector loop, this->loops ) { - boost::python::list point_list; - BOOST_FOREACH( Point p, loop ) { - point_list.append( p ); - } - loop_list.append(point_list); + public: + AdaptiveWaterline_py() : AdaptiveWaterline() {} + ~AdaptiveWaterline_py() { std::cout << "~AdaptiveWaterline_py()\n"; } + + /// return loop as a list of lists to python + boost::python::list py_getLoops() const { + boost::python::list loop_list; + BOOST_FOREACH (std::vector loop, this->loops) { + boost::python::list point_list; + BOOST_FOREACH (Point p, loop) { + point_list.append(p); } - return loop_list; + loop_list.append(point_list); } - /// return a list of xfibers to python - boost::python::list getXFibers() const { - boost::python::list flist; - BOOST_FOREACH( Fiber f, xfibers ) { - if (!f.empty()) { - Fiber_py f2(f); - flist.append(f2); - } + return loop_list; + } + /// return a list of xfibers to python + boost::python::list getXFibers() const { + boost::python::list flist; + BOOST_FOREACH (Fiber f, xfibers) { + if (!f.empty()) { + Fiber_py f2(f); + flist.append(f2); } - return flist; } - /// return a list of yfibers to python - boost::python::list getYFibers() const { - boost::python::list flist; - BOOST_FOREACH( Fiber f, yfibers ) { - if (!f.empty()){ - Fiber_py f2(f); - flist.append(f2); - } + return flist; + } + /// return a list of yfibers to python + boost::python::list getYFibers() const { + boost::python::list flist; + BOOST_FOREACH (Fiber f, yfibers) { + if (!f.empty()) { + Fiber_py f2(f); + flist.append(f2); } - return flist; } + return flist; + } }; -} // end namespace +} // namespace ocl #endif diff --git a/src/pythonlib/batchdropcutter_py.hpp b/src/pythonlib/batchdropcutter_py.hpp index 53b89187..bb9e5c00 100644 --- a/src/pythonlib/batchdropcutter_py.hpp +++ b/src/pythonlib/batchdropcutter_py.hpp @@ -1,60 +1,59 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef BDC_PY_H #define BDC_PY_H -#include -#include +#include +#include #include "batchdropcutter.hpp" -namespace ocl -{ +namespace ocl { /// Python wrapper for BatchDropCutter class BatchDropCutter_py : public BatchDropCutter { - public: - BatchDropCutter_py() : BatchDropCutter() {}; - /// return CL-points to Python - boost::python::list getCLPoints_py() { - boost::python::list plist; - BOOST_FOREACH(CLPoint p, *clpoints) { - plist.append(p); - } - return plist; - }; - /// return triangles under cutter to Python. Not for CAM-algorithms, - /// more for visualization and demonstration. - boost::python::list getTrianglesUnderCutter(CLPoint& cl, MillingCutter& cutter) { - boost::python::list trilist; - std::list *triangles_under_cutter = new std::list(); - triangles_under_cutter = root->search_cutter_overlap( &cutter , &cl); - BOOST_FOREACH(Triangle t, *triangles_under_cutter) { - trilist.append(t); - } - delete triangles_under_cutter; - return trilist; - }; + public: + BatchDropCutter_py() : BatchDropCutter(){}; + /// return CL-points to Python + boost::python::list getCLPoints_py() { + boost::python::list plist; + BOOST_FOREACH (CLPoint p, *clpoints) { + plist.append(p); + } + return plist; + }; + /// return triangles under cutter to Python. Not for CAM-algorithms, + /// more for visualization and demonstration. + boost::python::list getTrianglesUnderCutter(CLPoint &cl, MillingCutter &cutter) { + boost::python::list trilist; + std::list *triangles_under_cutter = new std::list(); + triangles_under_cutter = root->search_cutter_overlap(&cutter, &cl); + BOOST_FOREACH (Triangle t, *triangles_under_cutter) { + trilist.append(t); + } + delete triangles_under_cutter; + return trilist; + }; }; -} // end namespace +} // namespace ocl #endif diff --git a/src/pythonlib/batchpushcutter_py.hpp b/src/pythonlib/batchpushcutter_py.hpp index f2111815..3d54e212 100644 --- a/src/pythonlib/batchpushcutter_py.hpp +++ b/src/pythonlib/batchpushcutter_py.hpp @@ -1,23 +1,23 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef BPC_PY_H #define BPC_PY_H @@ -28,71 +28,68 @@ #include "fiber_py.hpp" -namespace ocl -{ +namespace ocl { /// \brief python wrapper for batchpushcutter class BatchPushCutter_py : public BatchPushCutter { - public: - BatchPushCutter_py() : BatchPushCutter() {} - /// return CL-points to Python - boost::python::list getCLPoints_py() const { - boost::python::list plist; - BOOST_FOREACH(Fiber f, *fibers) { - BOOST_FOREACH( Interval i, f.ints ) { - if ( !i.empty() ) { - Point tmp = f.point(i.lower); - CLPoint p1 = CLPoint( tmp.x, tmp.y, tmp.z ); - p1.cc = new CCPoint(i.lower_cc); - tmp = f.point(i.upper); - CLPoint p2 = CLPoint( tmp.x, tmp.y, tmp.z ); - p2.cc = new CCPoint(i.upper_cc); - plist.append(p1); - plist.append(p2); - } + public: + BatchPushCutter_py() : BatchPushCutter() {} + /// return CL-points to Python + boost::python::list getCLPoints_py() const { + boost::python::list plist; + BOOST_FOREACH (Fiber f, *fibers) { + BOOST_FOREACH (Interval i, f.ints) { + if (!i.empty()) { + Point tmp = f.point(i.lower); + CLPoint p1 = CLPoint(tmp.x, tmp.y, tmp.z); + p1.cc = new CCPoint(i.lower_cc); + tmp = f.point(i.upper); + CLPoint p2 = CLPoint(tmp.x, tmp.y, tmp.z); + p2.cc = new CCPoint(i.upper_cc); + plist.append(p1); + plist.append(p2); } - } - return plist; - }; - /// return triangles under cutter to Python. Not for CAM-algorithms, - /// more for visualization and demonstration. - boost::python::list getOverlapTriangles(Fiber& f) { - boost::python::list trilist; - std::list *overlap_triangles = new std::list(); - //int plane = 3; // XY-plane - //Bbox bb; //FIXME - //KDNode2::search_kdtree( overlap_triangles, bb, root, plane); - CLPoint cl; - if (x_direction) { - cl.x = 0; - cl.y = f.p1.y; - cl.z = f.p1.z; - } else if (y_direction) { - cl.x = f.p1.x; - cl.y = 0; - cl.z = f.p1.z; - } else { - assert(0); - } - overlap_triangles = root->search_cutter_overlap(cutter, &cl); - - BOOST_FOREACH(Triangle t, *overlap_triangles) { - trilist.append(t); - } - delete overlap_triangles; - return trilist; - }; - /// return list of Fibers to python - boost::python::list getFibers_py() const { - boost::python::list flist; - BOOST_FOREACH(Fiber f, *fibers) { - flist.append( Fiber_py(f) ); - } - return flist; - }; + } + return plist; + }; + /// return triangles under cutter to Python. Not for CAM-algorithms, + /// more for visualization and demonstration. + boost::python::list getOverlapTriangles(Fiber &f) { + boost::python::list trilist; + std::list *overlap_triangles = new std::list(); + // int plane = 3; // XY-plane + // Bbox bb; //FIXME + // KDNode2::search_kdtree( overlap_triangles, bb, root, plane); + CLPoint cl; + if (x_direction) { + cl.x = 0; + cl.y = f.p1.y; + cl.z = f.p1.z; + } else if (y_direction) { + cl.x = f.p1.x; + cl.y = 0; + cl.z = f.p1.z; + } else { + assert(0); + } + overlap_triangles = root->search_cutter_overlap(cutter, &cl); + BOOST_FOREACH (Triangle t, *overlap_triangles) { + trilist.append(t); + } + delete overlap_triangles; + return trilist; + }; + /// return list of Fibers to python + boost::python::list getFibers_py() const { + boost::python::list flist; + BOOST_FOREACH (Fiber f, *fibers) { + flist.append(Fiber_py(f)); + } + return flist; + }; }; -} // end namespace +} // namespace ocl #endif diff --git a/src/pythonlib/fiber_py.hpp b/src/pythonlib/fiber_py.hpp index 52013ec0..d91df295 100644 --- a/src/pythonlib/fiber_py.hpp +++ b/src/pythonlib/fiber_py.hpp @@ -1,23 +1,23 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef FIBER_PY_H #define FIBER_PY_H @@ -26,27 +26,26 @@ #include "fiber.hpp" -namespace ocl -{ +namespace ocl { /// python wrapper for Fiber class Fiber_py : public Fiber { - public: - Fiber_py() : Fiber () {}; - /// construct p1-p2 fiber - Fiber_py(const Point &p1, const Point &p2) : Fiber(p1, p2) {}; - /// copy constructor - Fiber_py(const Fiber& f) : Fiber(f) {}; - /// return a list of intervals to python - boost::python::list getInts() const { - boost::python::list l; - BOOST_FOREACH( Interval i, ints) { - l.append( i ); - } - return l; - }; + public: + Fiber_py() : Fiber(){}; + /// construct p1-p2 fiber + Fiber_py(const Point &p1, const Point &p2) : Fiber(p1, p2){}; + /// copy constructor + Fiber_py(const Fiber &f) : Fiber(f){}; + /// return a list of intervals to python + boost::python::list getInts() const { + boost::python::list l; + BOOST_FOREACH (Interval i, ints) { + l.append(i); + } + return l; + }; }; -} // end namespace +} // namespace ocl #endif // end file fiber_py.h diff --git a/src/pythonlib/lineclfilter_py.hpp b/src/pythonlib/lineclfilter_py.hpp index 313826a7..7a588bff 100644 --- a/src/pythonlib/lineclfilter_py.hpp +++ b/src/pythonlib/lineclfilter_py.hpp @@ -1,23 +1,23 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef LINE_CL_FILTER_PY_H #define LINE_CL_FILTER_PY_H @@ -26,23 +26,22 @@ #include "lineclfilter.hpp" -namespace ocl -{ +namespace ocl { /// python wrapper for lineclfilter class LineCLFilter_py : public LineCLFilter { - public: - LineCLFilter_py() : LineCLFilter() {}; - /// return a list of CL-points to python - boost::python::list getCLPoints() { - // return points to python - boost::python::list plist; - BOOST_FOREACH(CLPoint p, clpoints) { - plist.append(p); - } - return plist; - }; + public: + LineCLFilter_py() : LineCLFilter(){}; + /// return a list of CL-points to python + boost::python::list getCLPoints() { + // return points to python + boost::python::list plist; + BOOST_FOREACH (CLPoint p, clpoints) { + plist.append(p); + } + return plist; + }; }; -} // end namespace +} // namespace ocl #endif // end file lineclfilter_py.h diff --git a/src/pythonlib/millingcutter_py.hpp b/src/pythonlib/millingcutter_py.hpp index 1f411d18..33f217d3 100644 --- a/src/pythonlib/millingcutter_py.hpp +++ b/src/pythonlib/millingcutter_py.hpp @@ -1,23 +1,23 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef MILLING_CUTTER_PY_H #define MILLING_CUTTER_PY_H @@ -26,72 +26,59 @@ #include "millingcutter.hpp" -namespace ocl -{ +namespace ocl { /* required wrapper class for virtual functions in boost-python */ /// \brief a wrapper required for boost-python // see documentation: // http://www.boost.org/doc/libs/1_43_0/libs/python/doc/tutorial/doc/html/python/exposing.html#python.inheritance -class MillingCutter_py : public MillingCutter, public boost::python::wrapper -{ - public: - // vertex - bool vertexDrop(CLPoint &cl, const Triangle &t) const { - if ( boost::python::override ovr_vertexDrop = this->get_override("vertexDrop")) - return ovr_vertexDrop(cl, t); - return MillingCutter::vertexDrop(cl, t); - } - /// python-wrapper boilerplate... - bool default_vertexDrop(CLPoint &cl, const Triangle &t) const { - return this->MillingCutter::vertexDrop(cl,t); - } - - // facet - bool facetDrop(CLPoint &cl, const Triangle &t) const { - if ( boost::python::override ovr_facetDrop = this->get_override("facetDrop")) - return ovr_facetDrop(cl, t); - return MillingCutter::facetDrop(cl, t); - } - /// python-wrapper boilerplate... - bool default_facetDrop(CLPoint &cl, const Triangle &t) const { - return this->MillingCutter::facetDrop(cl,t); - } - - - // edge - bool edgeDrop(CLPoint &cl, const Triangle &t) const { - if ( boost::python::override ovr_edgeDrop = this->get_override("edgeDrop")) - return ovr_edgeDrop(cl, t); - return MillingCutter::edgeDrop(cl, t); - } - /// python-wrapper boilerplate... - bool default_edgeDrop(CLPoint &cl, const Triangle &t) const { - return this->MillingCutter::edgeDrop(cl,t); - } - - MillingCutter* offsetCutter(double d) const { - if ( boost::python::override ovr_offsetCutter = this->get_override("offsetCutter") ) - return ovr_offsetCutter(d); - return MillingCutter::offsetCutter(d); - } - /// python-wrapper boilerplate... - MillingCutter* default_offsetCutter(double d) const { - return this->MillingCutter::offsetCutter(d); - } - - std::string str() const { - if ( boost::python::override ovr_str = this->get_override("str")) { - return ovr_str(); - } - return MillingCutter::str(); - } - /// python-wrapper boilerplate... - std::string default_str() const { - return this->MillingCutter::str(); +class MillingCutter_py : public MillingCutter, public boost::python::wrapper { + public: + // vertex + bool vertexDrop(CLPoint &cl, const Triangle &t) const { + if (boost::python::override ovr_vertexDrop = this->get_override("vertexDrop")) + return ovr_vertexDrop(cl, t); + return MillingCutter::vertexDrop(cl, t); + } + /// python-wrapper boilerplate... + bool default_vertexDrop(CLPoint &cl, const Triangle &t) const { return this->MillingCutter::vertexDrop(cl, t); } + + // facet + bool facetDrop(CLPoint &cl, const Triangle &t) const { + if (boost::python::override ovr_facetDrop = this->get_override("facetDrop")) + return ovr_facetDrop(cl, t); + return MillingCutter::facetDrop(cl, t); + } + /// python-wrapper boilerplate... + bool default_facetDrop(CLPoint &cl, const Triangle &t) const { return this->MillingCutter::facetDrop(cl, t); } + + // edge + bool edgeDrop(CLPoint &cl, const Triangle &t) const { + if (boost::python::override ovr_edgeDrop = this->get_override("edgeDrop")) + return ovr_edgeDrop(cl, t); + return MillingCutter::edgeDrop(cl, t); + } + /// python-wrapper boilerplate... + bool default_edgeDrop(CLPoint &cl, const Triangle &t) const { return this->MillingCutter::edgeDrop(cl, t); } + + MillingCutter *offsetCutter(double d) const { + if (boost::python::override ovr_offsetCutter = this->get_override("offsetCutter")) + return ovr_offsetCutter(d); + return MillingCutter::offsetCutter(d); + } + /// python-wrapper boilerplate... + MillingCutter *default_offsetCutter(double d) const { return this->MillingCutter::offsetCutter(d); } + + std::string str() const { + if (boost::python::override ovr_str = this->get_override("str")) { + return ovr_str(); } + return MillingCutter::str(); + } + /// python-wrapper boilerplate... + std::string default_str() const { return this->MillingCutter::str(); } }; -} // end namespace +} // namespace ocl #endif // end file millingcutter_py.h diff --git a/src/pythonlib/ocl.cpp b/src/pythonlib/ocl.cpp index 72f0efc8..ff841331 100644 --- a/src/pythonlib/ocl.cpp +++ b/src/pythonlib/ocl.cpp @@ -1,47 +1,42 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ // This is an extra comment. One can never have too many comments. #ifdef _OPENMP - #include +#include #endif #include #include #include "version_string.hpp" // autogenerated by version_string.cmake -std::string ocl_docstring() { - return "OpenCAMLib docstring"; -} +std::string ocl_docstring() { return "OpenCAMLib docstring"; } -std::string ocl_version() { - return VERSION_STRING; -} +std::string ocl_version() { return VERSION_STRING; } -int ocl_max_threads() -{ - #ifdef _OPENMP +int ocl_max_threads() { +#ifdef _OPENMP return omp_get_max_threads(); - #endif +#endif return 1; } @@ -55,27 +50,23 @@ void export_dropcutter(); // this defines the python ocl module BOOST_PYTHON_MODULE(ocl) { bp::docstring_options doc_options; -// these functions set the docstring options - //void disable_user_defined(); + // these functions set the docstring options + // void disable_user_defined(); void enable_user_defined(); - //void disable_signatures(); + // void disable_signatures(); void enable_signatures(); - //void disable_py_signatures(); + // void disable_py_signatures(); void enable_py_signatures(); - //void disable_cpp_signatures(); + // void disable_cpp_signatures(); void enable_cpp_signatures(); - //void disable_all(); - //void enable_all(); - + // void disable_all(); + // void enable_all(); + bp::def("__doc__", ocl_docstring); bp::def("version", ocl_version); bp::def("max_threads", ocl_max_threads); - export_geometry(); // see ocl_geometry.cpp - export_cutters(); // see ocl_cutters.cpp - export_algo(); // see ocl_algo.cpp + export_geometry(); // see ocl_geometry.cpp + export_cutters(); // see ocl_cutters.cpp + export_algo(); // see ocl_algo.cpp export_dropcutter(); // see ocl_dropcutter.cpp - } - - - diff --git a/src/pythonlib/ocl_algo.cpp b/src/pythonlib/ocl_algo.cpp index 33edb695..39f5bac4 100644 --- a/src/pythonlib/ocl_algo.cpp +++ b/src/pythonlib/ocl_algo.cpp @@ -1,34 +1,33 @@ /* $Id$ - * + * * Copyright (c) 2010-2011 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #include - -#include "batchpushcutter_py.hpp" -#include "fiber_py.hpp" -#include "weave_py.hpp" -#include "waterline_py.hpp" -#include "adaptivewaterline_py.hpp" -#include "lineclfilter_py.hpp" +#include "adaptivewaterline_py.hpp" +#include "batchpushcutter_py.hpp" +#include "fiber_py.hpp" +#include "lineclfilter_py.hpp" #include "numeric.hpp" +#include "waterline_py.hpp" +#include "weave_py.hpp" #include "zigzag_py.hpp" @@ -58,11 +57,9 @@ void export_algo() { .def("setStepOver", &ZigZag::setStepOver) .def("addPoint", &ZigZag::addPoint) .def("getOutput", &ZigZag_py::getOutput) - .def("__str__", &ZigZag::str) - ; + .def("__str__", &ZigZag::str); - bp::class_("BatchPushCutter_base") - ; + bp::class_("BatchPushCutter_base"); bp::class_>("BatchPushCutter") .def("run", &BatchPushCutter_py::run) .def("setSTL", &BatchPushCutter_py::setSTL) @@ -81,30 +78,26 @@ void export_algo() { .def("setYDirection", &BatchPushCutter_py::setYDirection); bp::class_("Interval") .def(bp::init()) - .def_readonly("upper", &Interval::upper ) - .def_readonly("lower", &Interval::lower ) - .def_readonly("lower_cc", &Interval::lower_cc ) - .def_readonly("upper_cc", &Interval::upper_cc ) - .def("updateUpper", &Interval::updateUpper ) - .def("updateLower", &Interval::updateLower ) - .def("empty", &Interval::empty ) - .def("__str__", &Interval::str ) - ; - bp::class_("Fiber_base") - ; - bp::class_ >("Fiber") - .def(bp::init()) + .def_readonly("upper", &Interval::upper) + .def_readonly("lower", &Interval::lower) + .def_readonly("lower_cc", &Interval::lower_cc) + .def_readonly("upper_cc", &Interval::upper_cc) + .def("updateUpper", &Interval::updateUpper) + .def("updateLower", &Interval::updateLower) + .def("empty", &Interval::empty) + .def("__str__", &Interval::str); + bp::class_("Fiber_base"); + bp::class_>("Fiber") + .def(bp::init()) .def_readonly("p1", &Fiber_py::p1) .def_readonly("p2", &Fiber_py::p2) .def_readonly("dir", &Fiber_py::dir) .def("addInterval", &Fiber_py::addInterval) .def("point", &Fiber_py::point) .def("printInts", &Fiber_py::printInts) - .def("getInts", &Fiber_py::getInts) - ; - bp::class_("Waterline_base") - ; - bp::class_ >("Waterline") + .def("getInts", &Fiber_py::getInts); + bp::class_("Waterline_base"); + bp::class_>("Waterline") .def("setCutter", &Waterline_py::setCutter) .def("setSTL", &Waterline_py::setSTL) .def("setZ", &Waterline_py::setZ) @@ -117,11 +110,10 @@ void export_algo() { .def("getThreads", &Waterline_py::getThreads) .def("getXFibers", &Waterline_py::py_getXFibers) .def("getYFibers", &Waterline_py::py_getYFibers) - - ; - bp::class_("AdaptiveWaterline_base") - ; - bp::class_ >("AdaptiveWaterline") + + ; + bp::class_("AdaptiveWaterline_base"); + bp::class_>("AdaptiveWaterline") .def("setCutter", &AdaptiveWaterline_py::setCutter) .def("setSTL", &AdaptiveWaterline_py::setSTL) .def("setZ", &AdaptiveWaterline_py::setZ) @@ -135,19 +127,16 @@ void export_algo() { .def("setThreads", &AdaptiveWaterline_py::setThreads) .def("getThreads", &AdaptiveWaterline_py::getThreads) .def("getXFibers", &AdaptiveWaterline_py::getXFibers) - .def("getYFibers", &AdaptiveWaterline_py::getYFibers) - ; - + .def("getYFibers", &AdaptiveWaterline_py::getYFibers); + bp::enum_("WeaveVertexType") .value("CL", weave::CL) - .value("CL_DONE",weave::CL_DONE) - .value("ADJ",weave::ADJ) - .value("TWOADJ",weave::TWOADJ) - .value("INT",weave::INT) - .value("FULLINT",weave::FULLINT) - ; - - + .value("CL_DONE", weave::CL_DONE) + .value("ADJ", weave::ADJ) + .value("TWOADJ", weave::TWOADJ) + .value("INT", weave::INT) + .value("FULLINT", weave::FULLINT); + /* bp::class_("Weave_base") ; @@ -168,18 +157,16 @@ void export_algo() { .def("__str__", &weave::Weave_py::str) ; */ - - bp::class_("LineCLFilter_base") - ; - bp::class_ >("LineCLFilter") - .def("addCLPoint", &LineCLFilter_py::addCLPoint) - .def("setTolerance",&LineCLFilter_py::setTolerance) - .def("run", &LineCLFilter_py::run) - .def("getCLPoints", &LineCLFilter_py::getCLPoints) - ; + + bp::class_("LineCLFilter_base"); + bp::class_>("LineCLFilter") + .def("addCLPoint", &LineCLFilter_py::addCLPoint) + .def("setTolerance", &LineCLFilter_py::setTolerance) + .def("run", &LineCLFilter_py::run) + .def("getCLPoints", &LineCLFilter_py::getCLPoints); // some strange problem with hedi::face_edges()... let's not compile for now.. - bp::class_< clsurf::CutterLocationSurface >("CutterLocationSurface") + bp::class_("CutterLocationSurface") .def(bp::init()) .def("run", &clsurf::CutterLocationSurface::run) .def("setMinSampling", &clsurf::CutterLocationSurface::setMinSampling) @@ -188,16 +175,14 @@ void export_algo() { .def("setCutter", &clsurf::CutterLocationSurface::setCutter) .def("getVertices", &clsurf::CutterLocationSurface::getVertices) .def("getEdges", &clsurf::CutterLocationSurface::getEdges) - .def("__str__", &clsurf::CutterLocationSurface::str) - ; -/* - bp::class_< tsp::TSPSolver >("TSPSolver") - .def("addPoint", &tsp::TSPSolver::addPoint) - .def("run", &tsp::TSPSolver::run) - .def("getOutput", &tsp::TSPSolver::getOutput) - .def("getLength", &tsp::TSPSolver::getLength) - .def("reset", &tsp::TSPSolver::reset) - ; - */ + .def("__str__", &clsurf::CutterLocationSurface::str); + /* + bp::class_< tsp::TSPSolver >("TSPSolver") + .def("addPoint", &tsp::TSPSolver::addPoint) + .def("run", &tsp::TSPSolver::run) + .def("getOutput", &tsp::TSPSolver::getOutput) + .def("getLength", &tsp::TSPSolver::getLength) + .def("reset", &tsp::TSPSolver::reset) + ; + */ } - diff --git a/src/pythonlib/ocl_cutters.cpp b/src/pythonlib/ocl_cutters.cpp index 714cea9d..bec6c10a 100644 --- a/src/pythonlib/ocl_cutters.cpp +++ b/src/pythonlib/ocl_cutters.cpp @@ -1,33 +1,33 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #include -#include "millingcutter.hpp" -#include "millingcutter_py.hpp" -#include "cylcutter.hpp" #include "ballcutter.hpp" #include "bullcutter.hpp" -#include "conecutter.hpp" #include "compositecutter.hpp" +#include "conecutter.hpp" +#include "cylcutter.hpp" +#include "millingcutter.hpp" +#include "millingcutter_py.hpp" /* * wrap cutters @@ -38,54 +38,36 @@ using namespace ocl; namespace bp = boost::python; void export_cutters() { -// documentation here: -// http://www.boost.org/doc/libs/1_43_0/libs/python/doc/tutorial/doc/html/python/exposing.html#python.inheritance + // documentation here: + // http://www.boost.org/doc/libs/1_43_0/libs/python/doc/tutorial/doc/html/python/exposing.html#python.inheritance - bp::class_("MillingCutter") - .def("vertexDrop", &MillingCutter::vertexDrop, &MillingCutter_py::default_vertexDrop ) - .def("facetDrop", &MillingCutter::facetDrop, &MillingCutter_py::default_facetDrop ) - .def("edgeDrop", &MillingCutter::edgeDrop, &MillingCutter_py::default_edgeDrop ) + bp::class_("MillingCutter") + .def("vertexDrop", &MillingCutter::vertexDrop, &MillingCutter_py::default_vertexDrop) + .def("facetDrop", &MillingCutter::facetDrop, &MillingCutter_py::default_facetDrop) + .def("edgeDrop", &MillingCutter::edgeDrop, &MillingCutter_py::default_edgeDrop) .def("dropCutter", &MillingCutter::dropCutter) .def("pushCutter", &MillingCutter::pushCutter) - .def("offsetCutter", &MillingCutter::offsetCutter, bp::return_value_policy() ) - .def("__str__", &MillingCutter::str, &MillingCutter_py::default_str ) - .def("getRadius", &MillingCutter::getRadius ) - .def("getLength", &MillingCutter::getLength ) - .def("getDiameter", &MillingCutter::getDiameter ) - ; - bp::class_ >("CylCutter") - .def(bp::init()) - .def("dropCutterSTL", &CylCutter::dropCutterSTL) - ; - bp::class_ >("BallCutter") - .def(bp::init()) - .def("dropCutterSTL", &BallCutter::dropCutterSTL) - ; - bp::class_ >("BullCutter") - .def(bp::init()) - ; - bp::class_ >("ConeCutter") - .def(bp::init()) - ; - - bp::class_ >("CompCylCutter") + .def("offsetCutter", &MillingCutter::offsetCutter, bp::return_value_policy()) + .def("__str__", &MillingCutter::str, &MillingCutter_py::default_str) + .def("getRadius", &MillingCutter::getRadius) + .def("getLength", &MillingCutter::getLength) + .def("getDiameter", &MillingCutter::getDiameter); + bp::class_>("CylCutter") .def(bp::init()) - ; - bp::class_ >("CompBallCutter") + .def("dropCutterSTL", &CylCutter::dropCutterSTL); + bp::class_>("BallCutter") .def(bp::init()) - ; - - bp::class_ >("CylConeCutter") - .def(bp::init()) - ; - bp::class_ >("BallConeCutter") - .def(bp::init()) - ; - bp::class_ >("BullConeCutter") - .def(bp::init()) - ; - bp::class_ >("ConeConeCutter") - .def(bp::init()) - ; -} + .def("dropCutterSTL", &BallCutter::dropCutterSTL); + bp::class_>("BullCutter").def(bp::init()); + bp::class_>("ConeCutter").def(bp::init()); + + bp::class_>("CompCylCutter").def(bp::init()); + bp::class_>("CompBallCutter").def(bp::init()); + bp::class_>("CylConeCutter").def(bp::init()); + bp::class_>("BallConeCutter").def(bp::init()); + bp::class_>("BullConeCutter") + .def(bp::init()); + bp::class_>("ConeConeCutter") + .def(bp::init()); +} diff --git a/src/pythonlib/ocl_dropcutter.cpp b/src/pythonlib/ocl_dropcutter.cpp index 2f929d99..3e214984 100644 --- a/src/pythonlib/ocl_dropcutter.cpp +++ b/src/pythonlib/ocl_dropcutter.cpp @@ -1,30 +1,29 @@ /* $Id$ - * + * * Copyright (c) 2010-2011 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #include -#include "batchdropcutter_py.hpp" -#include "pathdropcutter_py.hpp" -#include "adaptivepathdropcutter_py.hpp" - +#include "adaptivepathdropcutter_py.hpp" +#include "batchdropcutter_py.hpp" +#include "pathdropcutter_py.hpp" /* * Python wrapping of octree and related classes @@ -36,9 +35,8 @@ namespace bp = boost::python; void export_dropcutter() { - bp::class_("BatchDropCutter_base") - ; - bp::class_ >("BatchDropCutter") + bp::class_("BatchDropCutter_base"); + bp::class_>("BatchDropCutter") .def("run", &BatchDropCutter_py::run) .def("getCLPoints", &BatchDropCutter_py::getCLPoints_py) .def("setSTL", &BatchDropCutter_py::setSTL) @@ -49,13 +47,10 @@ void export_dropcutter() { .def("getTrianglesUnderCutter", &BatchDropCutter_py::getTrianglesUnderCutter) .def("getCalls", &BatchDropCutter_py::getCalls) .def("getBucketSize", &BatchDropCutter_py::getBucketSize) - .def("setBucketSize", &BatchDropCutter_py::setBucketSize) - ; - + .def("setBucketSize", &BatchDropCutter_py::setBucketSize); - bp::class_("PathDropCutter_base") - ; - bp::class_ >("PathDropCutter") + bp::class_("PathDropCutter_base"); + bp::class_>("PathDropCutter") .def("run", &PathDropCutter_py::run) .def("getCLPoints", &PathDropCutter_py::getCLPoints_py) .def("setCutter", &PathDropCutter_py::setCutter) @@ -63,11 +58,9 @@ void export_dropcutter() { .def("setSampling", &PathDropCutter_py::setSampling) .def("setPath", &PathDropCutter_py::setPath) .def("getZ", &PathDropCutter_py::getZ) - .def("setZ", &PathDropCutter_py::setZ) - ; - bp::class_("AdaptivePathDropCutter_base") - ; - bp::class_ >("AdaptivePathDropCutter") + .def("setZ", &PathDropCutter_py::setZ); + bp::class_("AdaptivePathDropCutter_base"); + bp::class_>("AdaptivePathDropCutter") .def("run", &AdaptivePathDropCutter_py::run) .def("getCLPoints", &AdaptivePathDropCutter_py::getCLPoints_py) .def("setCutter", &AdaptivePathDropCutter_py::setCutter) @@ -78,9 +71,5 @@ void export_dropcutter() { .def("getSampling", &AdaptivePathDropCutter_py::getSampling) .def("setPath", &AdaptivePathDropCutter_py::setPath) .def("getZ", &AdaptivePathDropCutter_py::getZ) - .def("setZ", &AdaptivePathDropCutter_py::setZ) - ; - - + .def("setZ", &AdaptivePathDropCutter_py::setZ); } - diff --git a/src/pythonlib/ocl_geometry.cpp b/src/pythonlib/ocl_geometry.cpp index 81151a14..d02821c1 100644 --- a/src/pythonlib/ocl_geometry.cpp +++ b/src/pythonlib/ocl_geometry.cpp @@ -1,35 +1,35 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #include -#include "point.hpp" // contains no python-specific code -#include "ccpoint.hpp" // no python -#include "clpoint.hpp" // no python -#include "triangle_py.hpp" // new-style python wrapper-class -#include "stlsurf_py.hpp" // new-style wrapper -#include "ellipse.hpp" // no python +#include "bbox.hpp" // no python +#include "ccpoint.hpp" // no python +#include "clpoint.hpp" // no python +#include "ellipse.hpp" // no python #include "ellipseposition.hpp" -#include "bbox.hpp" // no python -#include "path_py.hpp" // new-style wrapper -#include "stlreader.hpp" // no python +#include "path_py.hpp" // new-style wrapper +#include "point.hpp" // contains no python-specific code +#include "stlreader.hpp" // no python +#include "stlsurf_py.hpp" // new-style wrapper +#include "triangle_py.hpp" // new-style python wrapper-class /* * Python wrapping @@ -39,9 +39,8 @@ using namespace ocl; namespace bp = boost::python; - void export_geometry() { - bp::class_("Point") + bp::class_("Point") .def(bp::init()) .def(bp::init()) .def(bp::init()) @@ -66,60 +65,55 @@ void export_geometry() { .def("__str__", &Point::str) .def_readwrite("x", &Point::x) .def_readwrite("y", &Point::y) - .def_readwrite("z", &Point::z) - ; - bp::class_("CLPoint") // FIXME: should inherit from Point + .def_readwrite("z", &Point::z); + bp::class_("CLPoint") // FIXME: should inherit from Point .def(bp::init()) .def(bp::init()) - .def(bp::init()) + .def(bp::init()) .def("__str__", &CLPoint::str) .def_readwrite("x", &CLPoint::x) .def_readwrite("y", &CLPoint::y) .def_readwrite("z", &CLPoint::z) .def("cc", &CLPoint::getCC) - .def("getCC", &CLPoint::getCC) - ; - bp::class_("CCPoint") // FIXME: CCPoint should inherit from Point + .def("getCC", &CLPoint::getCC); + bp::class_("CCPoint") // FIXME: CCPoint should inherit from Point .def(bp::init()) .def(bp::init()) .def("__str__", &CCPoint::str) .def_readwrite("type", &CCPoint::type) .def_readwrite("x", &CCPoint::x) .def_readwrite("y", &CCPoint::y) - .def_readwrite("z", &CCPoint::z) - ; + .def_readwrite("z", &CCPoint::z); bp::enum_("CCType") .value("NONE", NONE) - .value("VERTEX",VERTEX) - .value("VERTEX_CYL",VERTEX_CYL) - .value("EDGE",EDGE) - .value("EDGE_SHAFT",EDGE_SHAFT) - .value("EDGE_HORIZ",EDGE_HORIZ) - .value("EDGE_CYL",EDGE_CYL) - .value("EDGE_BALL",EDGE_BALL) - .value("EDGE_CONE",EDGE_CONE) - .value("EDGE_CONE_BASE",EDGE_CONE_BASE) - .value("EDGE_HORIZ_CYL",EDGE_HORIZ_CYL) - .value("EDGE_HORIZ_TOR",EDGE_HORIZ_TOR) - .value("EDGE_POS",EDGE_POS) - .value("EDGE_NEG",EDGE_NEG) + .value("VERTEX", VERTEX) + .value("VERTEX_CYL", VERTEX_CYL) + .value("EDGE", EDGE) + .value("EDGE_SHAFT", EDGE_SHAFT) + .value("EDGE_HORIZ", EDGE_HORIZ) + .value("EDGE_CYL", EDGE_CYL) + .value("EDGE_BALL", EDGE_BALL) + .value("EDGE_CONE", EDGE_CONE) + .value("EDGE_CONE_BASE", EDGE_CONE_BASE) + .value("EDGE_HORIZ_CYL", EDGE_HORIZ_CYL) + .value("EDGE_HORIZ_TOR", EDGE_HORIZ_TOR) + .value("EDGE_POS", EDGE_POS) + .value("EDGE_NEG", EDGE_NEG) .value("FACET", FACET) .value("FACET_TIP", FACET_TIP) .value("FACET_CYL", FACET_CYL) - .value("ERROR", ERROR) - ; + .value("ERROR", ERROR); bp::class_("Triangle_base") // needed by Triangle_py as a base-class - ; - bp::class_ >("Triangle") - .def(bp::init()) + ; + bp::class_>("Triangle") + .def(bp::init()) .def("getPoints", &Triangle_py::getPoints) - .def("__str__", &Triangle_py::str) + .def("__str__", &Triangle_py::str) .def_readonly("p", &Triangle_py::p) - .def_readonly("n", &Triangle_py::n) - ; + .def_readonly("n", &Triangle_py::n); bp::class_("STLSurf_base") // needed by STLSurf_py below - ; - bp::class_ >("STLSurf") + ; + bp::class_>("STLSurf") .def("addTriangle", &STLSurf_py::addTriangle) .def("__str__", &STLSurf_py::str) .def("size", &STLSurf_py::size) @@ -127,57 +121,45 @@ void export_geometry() { .def("getBounds", &STLSurf_py::getBounds) .def("getTriangles", &STLSurf_py::getTriangles) .def_readonly("tris", &STLSurf_py::tris) - .def_readonly("bb", &STLSurf_py::bb) - ; - bp::class_("STLReader") - .def(bp::init()) - ; + .def_readonly("bb", &STLSurf_py::bb); + bp::class_("STLReader").def(bp::init()); bp::class_("Bbox") - .def("isInside", &Bbox::isInside ) + .def("isInside", &Bbox::isInside) .def_readonly("maxpt", &Bbox::maxpt) - .def_readonly("minpt", &Bbox::minpt) - ; + .def_readonly("minpt", &Bbox::minpt); // Epos and the Ellipse are used for the toroidal tool edge-tests bp::class_("EllipsePosition") .def_readwrite("s", &EllipsePosition::s) .def_readwrite("t", &EllipsePosition::t) .def("setDiangle", &EllipsePosition::setDiangle) - .def("__str__", &EllipsePosition::str) - ; + .def("__str__", &EllipsePosition::str); bp::class_("Ellipse") - .def(bp::init()) + .def(bp::init()) .def("ePoint", &Ellipse::ePoint) .def("oePoint", &Ellipse::oePoint) - .def("normal", &Ellipse::normal) - ; + .def("normal", &Ellipse::normal); bp::class_("Line") - .def(bp::init()) + .def(bp::init()) .def(bp::init()) .def_readwrite("p1", &Line::p1) - .def_readwrite("p2", &Line::p2) - ; + .def_readwrite("p2", &Line::p2); bp::class_("Arc") - .def(bp::init()) + .def(bp::init()) .def(bp::init()) .def_readwrite("p1", &Arc::p1) .def_readwrite("p2", &Arc::p2) - .def_readwrite("c", &Arc::c) - .def_readwrite("dir", &Arc::dir) - ; + .def_readwrite("c", &Arc::c) + .def_readwrite("dir", &Arc::dir); bp::enum_("SpanType") .value("LineSpanType", LineSpanType) .value("ArcSpanType", ArcSpanType) - .export_values() - ; - bp::class_("Path_base") - ; - bp::class_ >("Path") + .export_values(); + bp::class_("Path_base"); + bp::class_>("Path") .def(bp::init<>()) .def(bp::init()) .def("getSpans", &Path_py::getSpans) .def("getTypeSpanPairs", &Path_py::getTypeSpanPairs) - .def("append",static_cast< void (Path_py::*)(const Line &l)>(&Path_py::append)) - .def("append",static_cast< void (Path_py::*)(const Arc &a)>(&Path_py::append)) - ; + .def("append", static_cast(&Path_py::append)) + .def("append", static_cast(&Path_py::append)); } - diff --git a/src/pythonlib/path_py.hpp b/src/pythonlib/path_py.hpp index c8ff0cda..beafdb3c 100644 --- a/src/pythonlib/path_py.hpp +++ b/src/pythonlib/path_py.hpp @@ -1,80 +1,74 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef PATH_PY_H #define PATH_PY_H #include -#include #include +#include #include "path.hpp" - - -namespace ocl -{ +namespace ocl { /// Python wrapper for Path class Path_py : public Path { - public: - Path_py() : Path () {}; - /// copy constructor - Path_py(const Path &p) : Path(p) {}; - - /// return the span-list to python - boost::python::list getSpans() { - boost::python::list slist; - BOOST_FOREACH(Span* span, span_list) { - if(span->type() == LineSpanType)slist.append(((LineSpan*)span)->line); - else if(span->type() == ArcSpanType)slist.append(((ArcSpan*)span)->arc); - } - return slist; - }; + public: + Path_py() : Path(){}; + /// copy constructor + Path_py(const Path &p) : Path(p){}; + + /// return the span-list to python + boost::python::list getSpans() { + boost::python::list slist; + BOOST_FOREACH (Span *span, span_list) { + if (span->type() == LineSpanType) + slist.append(((LineSpan *)span)->line); + else if (span->type() == ArcSpanType) + slist.append(((ArcSpan *)span)->arc); + } + return slist; + }; - /// return a list of type/span pairs - boost::python::list getTypeSpanPairs() { - boost::python::list slist; - BOOST_FOREACH(Span* span, span_list) { - if(span->type() == LineSpanType) - { - boost::python::list tuple; - tuple.append(span->type()); - tuple.append(((LineSpan*)span)->line); - slist.append(tuple); - } - else if(span->type() == ArcSpanType) - { - boost::python::list tuple; - tuple.append(span->type()); - tuple.append(((ArcSpan*)span)->arc); - slist.append(tuple); - } + /// return a list of type/span pairs + boost::python::list getTypeSpanPairs() { + boost::python::list slist; + BOOST_FOREACH (Span *span, span_list) { + if (span->type() == LineSpanType) { + boost::python::list tuple; + tuple.append(span->type()); + tuple.append(((LineSpan *)span)->line); + slist.append(tuple); + } else if (span->type() == ArcSpanType) { + boost::python::list tuple; + tuple.append(span->type()); + tuple.append(((ArcSpan *)span)->arc); + slist.append(tuple); } - return slist; - }; - - + } + return slist; + }; }; -} // end namespace +} // namespace ocl #endif // end file path.h diff --git a/src/pythonlib/pathdropcutter_py.hpp b/src/pythonlib/pathdropcutter_py.hpp index 915a77f3..cae7b059 100644 --- a/src/pythonlib/pathdropcutter_py.hpp +++ b/src/pythonlib/pathdropcutter_py.hpp @@ -1,49 +1,48 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef PATHDROPCUTTER_PY_H #define PATHDROPCUTTER_PY_H -#include -#include +#include +#include #include "pathdropcutter.hpp" -namespace ocl -{ +namespace ocl { /// Python wrapper for PathDropCutter class PathDropCutter_py : public PathDropCutter { - public: - PathDropCutter_py() : PathDropCutter() {}; - /// return a list of CL-points to python - boost::python::list getCLPoints_py() { - boost::python::list plist; - BOOST_FOREACH(CLPoint p, clpoints) { - plist.append(p); - } - return plist; - }; + public: + PathDropCutter_py() : PathDropCutter(){}; + /// return a list of CL-points to python + boost::python::list getCLPoints_py() { + boost::python::list plist; + BOOST_FOREACH (CLPoint p, clpoints) { + plist.append(p); + } + return plist; + }; }; -} // end namespace +} // namespace ocl #endif // end file pathdropcutter_py.h diff --git a/src/pythonlib/stlsurf_py.hpp b/src/pythonlib/stlsurf_py.hpp index 9b74aa0d..d3b7f2df 100644 --- a/src/pythonlib/stlsurf_py.hpp +++ b/src/pythonlib/stlsurf_py.hpp @@ -1,68 +1,67 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef STLSURF_PY_H #define STLSURF_PY_H -#include #include +#include #include "stlsurf.hpp" -namespace ocl -{ - +namespace ocl { + /// STLSurf python wrapper class STLSurf_py : public STLSurf { - public: - /// default constructor - STLSurf_py() : STLSurf() {}; - /// return list of all triangles to python - boost::python::list getTriangles() const { - boost::python::list tlist; - BOOST_FOREACH(Triangle t, tris) { - tlist.append(Triangle_py(t)); - } - return tlist; - }; - - /// return bounds in a list to python - boost::python::list getBounds() const { - boost::python::list bounds; - bounds.append( bb.minpt.x ); - bounds.append( bb.maxpt.x ); - bounds.append( bb.minpt.y ); - bounds.append( bb.maxpt.y ); - bounds.append( bb.minpt.z ); - bounds.append( bb.maxpt.z ); - return bounds; - }; - - /// string output - std::string str() const { - std::ostringstream o; - o << *this; - return o.str(); - }; + public: + /// default constructor + STLSurf_py() : STLSurf(){}; + /// return list of all triangles to python + boost::python::list getTriangles() const { + boost::python::list tlist; + BOOST_FOREACH (Triangle t, tris) { + tlist.append(Triangle_py(t)); + } + return tlist; + }; + + /// return bounds in a list to python + boost::python::list getBounds() const { + boost::python::list bounds; + bounds.append(bb.minpt.x); + bounds.append(bb.maxpt.x); + bounds.append(bb.minpt.y); + bounds.append(bb.maxpt.y); + bounds.append(bb.minpt.z); + bounds.append(bb.maxpt.z); + return bounds; + }; + + /// string output + std::string str() const { + std::ostringstream o; + o << *this; + return o.str(); + }; }; -} // end namespace +} // namespace ocl #endif // end file stlsurf_py.h diff --git a/src/pythonlib/triangle_py.hpp b/src/pythonlib/triangle_py.hpp index 1ba28f93..b479010f 100644 --- a/src/pythonlib/triangle_py.hpp +++ b/src/pythonlib/triangle_py.hpp @@ -1,70 +1,66 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef TRIANGLE_PY_H #define TRIANGLE_PY_H #include -#include #include +#include #include "triangle.hpp" -namespace ocl -{ +namespace ocl { /// /// \brief python wrapper for Triangle /// class Triangle_py : public Triangle { - public: - /// default constructor - Triangle_py() : Triangle() {}; - /// construct from three points - Triangle_py( const Point& p0, - const Point& p1, - const Point& p2) : Triangle(p0,p1,p2) {}; - /// copy constructor - Triangle_py( const Triangle_py& t) : Triangle(t) {}; - /// cast-down constructor - Triangle_py( const Triangle& t) : Triangle(t) {}; - - /// string repr - std::string str() const { - std::ostringstream o; - o << *this; - return o.str(); - }; - - /// Returns a list of the vertices to Python - boost::python::list getPoints() const { - boost::python::list plist; - BOOST_FOREACH(Point vertex, p) { - plist.append(vertex); - } - return plist; - }; - + public: + /// default constructor + Triangle_py() : Triangle(){}; + /// construct from three points + Triangle_py(const Point &p0, const Point &p1, const Point &p2) : Triangle(p0, p1, p2){}; + /// copy constructor + Triangle_py(const Triangle_py &t) : Triangle(t){}; + /// cast-down constructor + Triangle_py(const Triangle &t) : Triangle(t){}; + + /// string repr + std::string str() const { + std::ostringstream o; + o << *this; + return o.str(); + }; + + /// Returns a list of the vertices to Python + boost::python::list getPoints() const { + boost::python::list plist; + BOOST_FOREACH (Point vertex, p) { + plist.append(vertex); + } + return plist; + }; }; -} // end namespace +} // namespace ocl #endif // end file triangle_py.h diff --git a/src/pythonlib/waterline_py.hpp b/src/pythonlib/waterline_py.hpp index 0e679429..b93b364f 100644 --- a/src/pythonlib/waterline_py.hpp +++ b/src/pythonlib/waterline_py.hpp @@ -1,77 +1,73 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef WATERLINE_PY_H #define WATERLINE_PY_H -#include #include +#include #include "waterline.hpp" -namespace ocl -{ +namespace ocl { /// Python wrapper for Waterline class Waterline_py : public Waterline { - public: - Waterline_py() : Waterline() {} - ~Waterline_py() { - std::cout << "~Waterline_py()\n"; - } - /// return loop as a list of lists to python - boost::python::list py_getLoops() const { - boost::python::list loop_list; - BOOST_FOREACH( std::vector loop, this->loops ) { - boost::python::list point_list; - BOOST_FOREACH( Point p, loop ) { - point_list.append( p ); - } - loop_list.append(point_list); + public: + Waterline_py() : Waterline() {} + ~Waterline_py() { std::cout << "~Waterline_py()\n"; } + /// return loop as a list of lists to python + boost::python::list py_getLoops() const { + boost::python::list loop_list; + BOOST_FOREACH (std::vector loop, this->loops) { + boost::python::list point_list; + BOOST_FOREACH (Point p, loop) { + point_list.append(p); } - return loop_list; + loop_list.append(point_list); } - /// return a list of yfibers to python - boost::python::list py_getXFibers() const { - boost::python::list flist; - std::vector xfibers = *( subOp[0]->getFibers() ); - BOOST_FOREACH( Fiber f, xfibers ) { - Fiber_py f2(f); - flist.append(f2); - } - return flist; + return loop_list; + } + /// return a list of yfibers to python + boost::python::list py_getXFibers() const { + boost::python::list flist; + std::vector xfibers = *(subOp[0]->getFibers()); + BOOST_FOREACH (Fiber f, xfibers) { + Fiber_py f2(f); + flist.append(f2); } - /// return a list of yfibers to python - boost::python::list py_getYFibers() const { - boost::python::list flist; - std::vector yfibers = *( subOp[1]->getFibers() ); - BOOST_FOREACH( Fiber f, yfibers ) { - Fiber_py f2(f); - flist.append(f2); - } - return flist; + return flist; + } + /// return a list of yfibers to python + boost::python::list py_getYFibers() const { + boost::python::list flist; + std::vector yfibers = *(subOp[1]->getFibers()); + BOOST_FOREACH (Fiber f, yfibers) { + Fiber_py f2(f); + flist.append(f2); } - + return flist; + } }; -} // end namespace +} // namespace ocl #endif diff --git a/src/pythonlib/weave_py.h b/src/pythonlib/weave_py.h index 75999c38..7f028d21 100644 --- a/src/pythonlib/weave_py.h +++ b/src/pythonlib/weave_py.h @@ -1,102 +1,101 @@ /* $Id$ - * + * * Copyright (c) 2010 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef WEAVE_PY_H #define WEAVE_PY_H -#include // for py #include // for py +#include // for py #include "weave.h" -namespace ocl -{ +namespace ocl { /// Python wrapper for Weave class Weave_py : public Weave { - public: - Weave_py() : Weave() {}; + public: + Weave_py() : Weave(){}; // PYTHON - /// return graph components to python - boost::python::list get_components() { - boost::python::list wlist; - std::vector weaves = split_components(); - BOOST_FOREACH( Weave w, weaves ) { - wlist.append( w ); + /// return graph components to python + boost::python::list get_components() { + boost::python::list wlist; + std::vector weaves = split_components(); + BOOST_FOREACH (Weave w, weaves) { + wlist.append(w); + } + return wlist; + }; + /// return CL-points to python + boost::python::list getCLPoints() const { + boost::python::list plist; + VertexIterator it_begin, it_end, itr; + boost::tie(it_begin, it_end) = boost::vertices(g); + for (itr = it_begin; itr != it_end; ++itr) { + if (g[*itr].type == CL) + plist.append(g[*itr].position); + } + return plist; + }; + /// return internal points to python + boost::python::list getIPoints() const { + boost::python::list plist; + VertexIterator it_begin, it_end, itr; + boost::tie(it_begin, it_end) = boost::vertices(g); + for (itr = it_begin; itr != it_end; ++itr) { + if (g[*itr].type == INT) + plist.append(g[*itr].position); + } + return plist; + }; + /// return edges to python + /// format is [ [p1,p2] , [p3,p4] , ... ] + boost::python::list getEdges() const { + boost::python::list edge_list; + EdgeIterator it_begin, it_end, itr; + boost::tie(it_begin, it_end) = boost::edges(g); + for (itr = it_begin; itr != it_end; ++itr) { // loop through each edge + if (!boost::get(boost::edge_color, g, *itr)) { + boost::python::list point_list; // the endpoints of each edge + WeaveVertex v1 = boost::source(*itr, g); + WeaveVertex v2 = boost::target(*itr, g); + point_list.append(g[v1].position); + point_list.append(g[v2].position); + edge_list.append(point_list); } - return wlist; - }; - /// return CL-points to python - boost::python::list getCLPoints() const { - boost::python::list plist; - VertexIterator it_begin, it_end, itr; - boost::tie( it_begin, it_end ) = boost::vertices( g ); - for ( itr=it_begin ; itr != it_end ; ++itr ) { - if ( g[*itr].type == CL ) - plist.append( g[*itr].position ); + } + return edge_list; + }; + /// return loops to python + boost::python::list py_getLoops() const { + boost::python::list loop_list; + BOOST_FOREACH (std::vector loop, loops) { + boost::python::list point_list; + BOOST_FOREACH (WeaveVertex v, loop) { + point_list.append(g[v].position); } - return plist; - }; - /// return internal points to python - boost::python::list getIPoints() const { - boost::python::list plist; - VertexIterator it_begin, it_end, itr; - boost::tie( it_begin, it_end ) = boost::vertices( g ); - for ( itr=it_begin ; itr != it_end ; ++itr ) { - if ( g[*itr].type == INT ) - plist.append( g[*itr].position ); - } - return plist; - }; - /// return edges to python - /// format is [ [p1,p2] , [p3,p4] , ... ] - boost::python::list getEdges() const { - boost::python::list edge_list; - EdgeIterator it_begin, it_end, itr; - boost::tie( it_begin, it_end ) = boost::edges( g ); - for ( itr=it_begin ; itr != it_end ; ++itr ) { // loop through each edge - if ( ! boost::get( boost::edge_color, g, *itr ) ) { - boost::python::list point_list; // the endpoints of each edge - WeaveVertex v1 = boost::source( *itr, g ); - WeaveVertex v2 = boost::target( *itr, g ); - point_list.append(g[v1].position); - point_list.append(g[v2].position); - edge_list.append(point_list); - } - } - return edge_list; - }; - /// return loops to python - boost::python::list py_getLoops() const { - boost::python::list loop_list; - BOOST_FOREACH( std::vector loop, loops ) { - boost::python::list point_list; - BOOST_FOREACH( WeaveVertex v, loop ) { - point_list.append( g[v].position ); - } - loop_list.append(point_list); - } - return loop_list; - }; + loop_list.append(point_list); + } + return loop_list; + }; }; -} // end namespace +} // namespace ocl #endif // end file weave_py.h diff --git a/src/pythonlib/weave_py.hpp b/src/pythonlib/weave_py.hpp index 8480eb7d..e2409e1f 100644 --- a/src/pythonlib/weave_py.hpp +++ b/src/pythonlib/weave_py.hpp @@ -1,90 +1,82 @@ /* $Id$ - * + * * Copyright (c) 2010-2011 Anders Wallin (anders.e.e.wallin "at" gmail.com). - * - * This file is part of OpenCAMlib + * + * This file is part of OpenCAMlib * (see https://github.com/aewallin/opencamlib). - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . -*/ + */ #ifndef WEAVE_PY_H #define WEAVE_PY_H #include "weave.hpp" -namespace ocl -{ +namespace ocl { namespace weave { - + /// \brief python wrapper for VoronoiDiagram /// class Weave_py : public Weave { - public: - Weave_py() : Weave() {}; + public: + Weave_py() : Weave(){}; - int numVertices() const { - return g.num_vertices(); - }; - boost::python::list getVertices(VertexType t) { - boost::python::list plist; - BOOST_FOREACH( Vertex v, g.vertices() ) { - if ( g[v].type == t ) - plist.append( g[v].position ); - } - return plist; - }; - - /// return CL-points to python - boost::python::list getCLVertices() { - return getVertices( CL ); - }; - /// return internal points to python - boost::python::list getINTVertices() { - return getVertices( INT ); - }; - /// return edges to python - /// format is [ [p1,p2] , [p3,p4] , ... ] - boost::python::list getEdges() { - boost::python::list edge_list; - BOOST_FOREACH(Edge e, g.edges() ) { - boost::python::list point_list; // the endpoints of each edge - Vertex v1 = g.source( e ); - Vertex v2 = g.target( e ); - point_list.append(g[v1].position); - point_list.append(g[v2].position); - edge_list.append(point_list); - } - return edge_list; - }; - /// return loops to python - boost::python::list py_getLoops() { - boost::python::list loop_list; - BOOST_FOREACH( std::vector loop, loops ) { - boost::python::list point_list; - BOOST_FOREACH( Vertex v, loop ) { - point_list.append( g[v].position ); - } - loop_list.append(point_list); - } - return loop_list; - }; + int numVertices() const { return g.num_vertices(); }; + boost::python::list getVertices(VertexType t) { + boost::python::list plist; + BOOST_FOREACH (Vertex v, g.vertices()) { + if (g[v].type == t) + plist.append(g[v].position); + } + return plist; + }; + /// return CL-points to python + boost::python::list getCLVertices() { return getVertices(CL); }; + /// return internal points to python + boost::python::list getINTVertices() { return getVertices(INT); }; + /// return edges to python + /// format is [ [p1,p2] , [p3,p4] , ... ] + boost::python::list getEdges() { + boost::python::list edge_list; + BOOST_FOREACH (Edge e, g.edges()) { + boost::python::list point_list; // the endpoints of each edge + Vertex v1 = g.source(e); + Vertex v2 = g.target(e); + point_list.append(g[v1].position); + point_list.append(g[v2].position); + edge_list.append(point_list); + } + return edge_list; + }; + /// return loops to python + boost::python::list py_getLoops() { + boost::python::list loop_list; + BOOST_FOREACH (std::vector loop, loops) { + boost::python::list point_list; + BOOST_FOREACH (Vertex v, loop) { + point_list.append(g[v].position); + } + loop_list.append(point_list); + } + return loop_list; + }; }; -} // end weave namespace +} // namespace weave -} // end ocl namespace +} // namespace ocl #endif // end weave_py.h diff --git a/src/pythonlib/zigzag_py.hpp b/src/pythonlib/zigzag_py.hpp index 5825956f..54206b60 100644 --- a/src/pythonlib/zigzag_py.hpp +++ b/src/pythonlib/zigzag_py.hpp @@ -25,25 +25,21 @@ #include "zigzag.hpp" #include -namespace ocl -{ - /// \brief python wrapper for VoronoiDiagram - /// - class ZigZag_py : public ZigZag - { +namespace ocl { +/// \brief python wrapper for VoronoiDiagram +/// +class ZigZag_py : public ZigZag { public: ZigZag_py() : ZigZag(){}; - boost::python::list getOutput() const - { - boost::python::list o; - BOOST_FOREACH (Point p, out) - { - o.append(p); - } - return o; + boost::python::list getOutput() const { + boost::python::list o; + BOOST_FOREACH (Point p, out) { + o.append(p); + } + return o; } - }; -} // end ocl namespace +}; +} // namespace ocl #endif // end zigzag_py.hpp From c1c59a63d759686010db0787c7e99aa0e9192a27 Mon Sep 17 00:00:00 2001 From: Koen Schmeets Date: Mon, 9 Jan 2023 12:39:39 +0100 Subject: [PATCH 2/4] Add missing include --- src/common/brent_zero.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/common/brent_zero.hpp b/src/common/brent_zero.hpp index b364dd16..e71840a2 100644 --- a/src/common/brent_zero.hpp +++ b/src/common/brent_zero.hpp @@ -21,6 +21,8 @@ #ifndef BRENT_ZERO_H #define BRENT_ZERO_H +#include + namespace ocl { /// Brent's root finding algorithm From 255948b553ccb66d878d01473c7156e3f0a6d798 Mon Sep 17 00:00:00 2001 From: Koen Schmeets Date: Mon, 9 Jan 2023 15:43:45 +0100 Subject: [PATCH 3/4] Add missing include --- src/geo/stlreader.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/geo/stlreader.hpp b/src/geo/stlreader.hpp index 3e3db841..1fce9afb 100644 --- a/src/geo/stlreader.hpp +++ b/src/geo/stlreader.hpp @@ -22,6 +22,8 @@ #ifndef STLREADER_H #define STLREADER_H +#include + namespace ocl { class STLSurf; From 8d39d19b9db5b743019d3ed8b2d4a8512b77d456 Mon Sep 17 00:00:00 2001 From: Koen Schmeets Date: Mon, 9 Jan 2023 17:06:10 +0100 Subject: [PATCH 4/4] Add missing triangle_py.hpp include --- src/pythonlib/stlsurf_py.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pythonlib/stlsurf_py.hpp b/src/pythonlib/stlsurf_py.hpp index d3b7f2df..19f47acf 100644 --- a/src/pythonlib/stlsurf_py.hpp +++ b/src/pythonlib/stlsurf_py.hpp @@ -25,6 +25,7 @@ #include #include "stlsurf.hpp" +#include "triangle_py.hpp" namespace ocl {