diff --git a/src/Mod/Path/App/Area.cpp b/src/Mod/Path/App/Area.cpp index af4ceb7de6..16344ffd96 100644 --- a/src/Mod/Path/App/Area.cpp +++ b/src/Mod/Path/App/Area.cpp @@ -1391,7 +1391,7 @@ TopoDS_Shape Area::toShape(CArea &area, short fill) { TopoDS_Compound compound;\ builder.MakeCompound(compound);\ for(shared_ptr area : mySections){\ - const TopoDS_Shape &s = area->_op(-1, ## __VA_ARGS__);\ + const TopoDS_Shape &s = area->_op(_index, ## __VA_ARGS__);\ if(s.IsNull()) continue;\ builder.Add(compound,s);\ }\ @@ -1399,7 +1399,7 @@ TopoDS_Shape Area::toShape(CArea &area, short fill) { return compound;\ return TopoDS_Shape();\ }\ - return mySections[_index]->_op(-1, ## __VA_ARGS__);\ + return mySections[_index]->_op(_index, ## __VA_ARGS__);\ }\ }while(0) @@ -1420,14 +1420,14 @@ TopoDS_Shape Area::getShape(int index) { myShapeDone = true; return myShape; } - myShape = makePocket(-1,PARAM_FIELDS(AREA_MY,AREA_PARAMS_POCKET)); + myShape = makePocket(index,PARAM_FIELDS(AREA_MY,AREA_PARAMS_POCKET)); myShapeDone = true; return myShape; } // if no pocket, do offset or thicken if(myParams.PocketMode == PocketModeNone){ - myShape = makeOffset(-1,PARAM_FIELDS(AREA_MY,AREA_PARAMS_OFFSET)); + myShape = makeOffset(index,PARAM_FIELDS(AREA_MY,AREA_PARAMS_OFFSET)); myShapeDone = true; return myShape; } @@ -1622,8 +1622,35 @@ TopoDS_Shape Area::makePocket(int index, PARAM_ARGS(PARAM_FARG,AREA_PARAMS_POCKE AREA_SECTION(makePocket,index,PARAM_FIELDS(PARAM_FARG,AREA_PARAMS_POCKET)); TIME_INIT(t); + bool done = false; + if(index>=0) { + if(fabs(angle_shift) >= Precision::Confusion()) + angle += index*angle_shift; + + if(fabs(shift)>=Precision::Confusion()) + shift *= index; + } + + if(angle<-360.0) + angle += ceil(fabs(angle)/360.0)*360.0; + else if(angle>360.0) + angle -= floor(angle/360.0)*360.0; + else if(angle<0.0) + angle += 360.0; + + if(shift<-stepover) + shift += ceil(fabs(shift)/stepover)*stepover; + else if(shift>stepover) + shift -= floor(shift/stepover)*stepover; + else if(shift<0.0) + shift += stepover; + + CAreaConfig conf(myParams); + + CArea out; PocketMode pm; + switch(mode) { case Area::PocketModeZigZag: pm = ZigZagPocketMode; @@ -1633,30 +1660,81 @@ TopoDS_Shape Area::makePocket(int index, PARAM_ARGS(PARAM_FARG,AREA_PARAMS_POCKE break; case Area::PocketModeOffset: { PARAM_DECLARE_INIT(PARAM_FNAME,AREA_PARAMS_OFFSET); - Offset = -tool_radius-extra_offset; + Offset = -tool_radius-extra_offset-shift; ExtraPass = -1; Stepover = -stepover; return makeOffset(index,PARAM_FIELDS(PARAM_FNAME,AREA_PARAMS_OFFSET)); }case Area::PocketModeZigZagOffset: pm = ZigZagThenSingleOffsetPocketMode; break; - default: + case Area::PocketModeLine: + case Area::PocketModeGrid: + case Area::PocketModeTriangle:{ + CBox2D box; + myArea->GetBox(box); + if(!box.m_valid) + throw Base::ValueError("failed to get bound box"); + double angles[4]; + int count=1; + angles[0] = 0.0; + if(mode == Area::PocketModeGrid){ + angles[1]=90.0; + count=2; + if(shift360.0) a-=360.0; + double offset = -r+shift; + for(int j=0;j Precision::Confusion()) { + double r = a*M_PI/180.0; + p1.Rotate(r); + p2.Rotate(r); + } + out.m_curves.emplace_back(); + CCurve &curve = out.m_curves.back(); + curve.m_vertices.emplace_back(p1+center); + curve.m_vertices.emplace_back(p2+center); + } + } + PARAM_ENUM_CONVERT(AREA_MY,PARAM_FNAME,PARAM_ENUM_EXCEPT,AREA_PARAMS_CLIPPER_FILL); + out.Clip(toClipperOp(OperationIntersection),myArea.get(), SubjectFill,ClipFill); + done = true; + break; + }default: throw Base::ValueError("unknown poket mode"); } - CAreaConfig conf(myParams); - CAreaPocketParams params( - tool_radius,extra_offset,stepover,from_center,pm,zig_angle); - CArea in(*myArea),out; - // MakePcoketToolPath internally uses libarea Offset which somehow demands - // reorder before input, otherwise nothing is shown. - in.Reorder(); - in.MakePocketToolpath(out.m_curves,params); + if(!done) { + CAreaPocketParams params( + tool_radius,extra_offset,stepover,from_center,pm,angle); + CArea in(*myArea),out; + // MakePcoketToolPath internally uses libarea Offset which somehow demands + // reorder before input, otherwise nothing is shown. + in.Reorder(); + in.MakePocketToolpath(out.m_curves,params); + } TIME_PRINT(t,"makePocket"); if(myParams.Thicken){ + TIME_INIT(t); out.Thicken(tool_radius); + TIME_PRINT(t,"thicken"); return toShape(out,FillFace); }else return toShape(out,FillNone); diff --git a/src/Mod/Path/App/AreaParams.h b/src/Mod/Path/App/AreaParams.h index 8e2f836c68..629eab7dc0 100644 --- a/src/Mod/Path/App/AreaParams.h +++ b/src/Mod/Path/App/AreaParams.h @@ -98,13 +98,18 @@ * */ #define AREA_PARAMS_POCKET \ ((enum,mode,PocketMode,0,"Selects the pocket toolpath pattern",\ - (None)(ZigZag)(Offset)(Spiral)(ZigZagOffset)))\ + (None)(ZigZag)(Offset)(Spiral)(ZigZagOffset)(Line)(Grid)(Triangle)))\ ((double,tool_radius,ToolRadius,1.0,"Tool radius for pocketing",App::PropertyLength))\ ((double,extra_offset,PocketExtraOffset,0.0,"Extra offset for pocketing",App::PropertyDistance))\ ((double,stepover,PocketStepover,0.0,\ "Cutter diameter to step over on each pass. If =0, use ToolRadius.",App::PropertyLength))\ ((bool,from_center,FromCenter,true,"Start pocketing from center"))\ - ((double,zig_angle,ZigAngle,45,"Zig angle in degree",App::PropertyAngle)) + ((double,angle,Angle,45,"Pattern angle in degree",App::PropertyAngle))\ + ((double,angle_shift,AngleShift,0.0,"Pattern angle shift for each section", App::PropertyAngle))\ + ((double,shift,Shift,0.0,"Pattern shift distance for each section.\n"\ + "The pocket patter will be shifted in othgnal direction by this amount for each section.\n"\ + "This gives a 3D pattern mainly for 3D printing. The shift only applies to 'Offset', 'Grid'\n"\ + "and 'Triangle'", App::PropertyDistance)) #define AREA_PARAMS_POCKET_CONF \ ((bool,thicken,Thicken,false,"Thicken the resulting wires with ToolRadius"))