@@ -99,6 +99,7 @@ void HangprinterKinematics::Init() noexcept
9999 constexpr float DefaultTorqueConstants[HANGPRINTER_AXES] = { 0 .0F };
100100
101101 ARRAY_INIT (anchors, DefaultAnchors);
102+ anchorMode = HangprinterAnchorMode::LastOnTop;
102103 printRadius = DefaultPrintRadius;
103104 spoolBuildupFactor = DefaultSpoolBuildupFactor;
104105 ARRAY_INIT (spoolRadii, DefaultSpoolRadii);
@@ -229,6 +230,8 @@ bool HangprinterKinematics::Configure(unsigned int mCode, GCodeBuffer& gb, const
229230 }
230231 else if (mCode == 666 )
231232 {
233+ // 0=None, 1=last-top, 2=all-top, 3-half-top, etc
234+ gb.TryGetUIValue (' T' , (uint32_t &)anchorMode, seen);
232235 gb.TryGetFValue (' Q' , spoolBuildupFactor, seen);
233236 gb.TryGetFloatArray (' R' , HANGPRINTER_AXES, spoolRadii, seen);
234237 gb.TryGetUIArray (' U' , HANGPRINTER_AXES, mechanicalAdvantage, seen);
@@ -470,25 +473,51 @@ static bool isSameSide(float const v0[3], float const v1[3], float const v2[3],
470473 return dot0*dot1 > 0 .0F ;
471474}
472475
473- // For each triangle side in a pseudo-pyramid, check if the point is inside the pyramid (Except for the base)
474- // Also check that any point below the line between two exterior anchors (all anchors are exterior except for the last one)
475- // is in the "inside part" all the way down to min_Z, however low it may be.
476- // To further limit the movements in the X and Y axes one can simply set a smaller print radius.
477- bool HangprinterKinematics::IsReachable (float axesCoords[MaxAxes], AxesBitmap axes) const noexcept /* override*/
476+ bool HangprinterKinematics::IsInsidePyramidSides (float const coords[3 ]) const noexcept
478477{
479- float const coords[3 ] = {axesCoords[X_AXIS], axesCoords[Y_AXIS], axesCoords[Z_AXIS]};
480478 bool reachable = true ;
481479
482480 // Check all the planes defined by triangle sides in the pyramid
483481 for (size_t i = 0 ; reachable && i < HANGPRINTER_AXES - 1 ; ++i) {
484482 reachable = reachable && isSameSide (anchors[i], anchors[(i+1 ) % (HANGPRINTER_AXES - 1 )], anchors[HANGPRINTER_AXES - 1 ], anchors[(i+2 ) % (HANGPRINTER_AXES - 1 )], coords);
485483 }
484+ return reachable;
485+ }
486+
487+ bool HangprinterKinematics::IsInsidePrismSides (float const coords[3 ], unsigned const discount_last) const noexcept
488+ {
489+ bool reachable = true ;
486490
487491 // For each side of the base, check the plane formed by side and another point bellow them in z.
488- for (size_t i = 0 ; reachable && i < HANGPRINTER_AXES - 1 ; ++i) {
492+ for (size_t i = 0 ; reachable && i < HANGPRINTER_AXES - discount_last ; ++i) {
489493 float const lower_point[3 ] = {anchors[i][0 ], anchors[i][1 ], anchors[i][2 ] - 1 };
490494 reachable = reachable && isSameSide (anchors[i], anchors[(i+1 ) % (HANGPRINTER_AXES - 1 )], lower_point, anchors[(i+2 ) % (HANGPRINTER_AXES - 1 )], coords);
491495 }
496+ return reachable;
497+ }
498+
499+ // For each triangle side in a pseudo-pyramid, check if the point is inside the pyramid (Except for the base)
500+ // Also check that any point below the line between two exterior anchors (all anchors are exterior except for the last one)
501+ // is in the "inside part" all the way down to min_Z, however low it may be.
502+ // To further limit the movements in the X and Y axes one can simply set a smaller print radius.
503+ bool HangprinterKinematics::IsReachable (float axesCoords[MaxAxes], AxesBitmap axes) const noexcept /* override*/
504+ {
505+ float const coords[3 ] = {axesCoords[X_AXIS], axesCoords[Y_AXIS], axesCoords[Z_AXIS]};
506+ bool reachable = true ;
507+
508+ switch (anchorMode) {
509+ case HangprinterAnchorMode::None:
510+ return true ;
511+
512+ // This reaches a pyramid on top of the lower prism if the bed is below the lower anchors
513+ case HangprinterAnchorMode::LastOnTop:
514+ default :
515+ reachable = reachable && IsInsidePyramidSides (coords);
516+ reachable = reachable && IsInsidePrismSides (coords, 1 );
517+
518+ case HangprinterAnchorMode::AllOnTop:
519+ reachable = reachable && IsInsidePrismSides (coords, 0 );
520+ };
492521
493522 return reachable;
494523}
0 commit comments