FullControlXYZ / fullcontrol

Python version of FullControl for toolpath design (and more) - the readme below is best source of information
GNU General Public License v3.0
649 stars 74 forks source link

Grid /plate design using square waves #59

Open scamiv opened 8 months ago

scamiv commented 8 months ago

I made a practical design for use as a LED Matrix diffusor. https://colab.research.google.com/gist/scamiv/92495fe963bf4ebaec8c7f5f459fb99d/fullcontrol_ledMatrix_grid.ipynb Thing: https://www.printables.com/model/709532-fast-print-fully-parametric-led-matrix-cover-diffu

I would greatly appreciate any feedback on how to solve this more elegantly. Problems i had/have: Currently the size of the base plate wave seems slightly smaller than expected. Is there a function the get the last point in a step list? Especially if the last object is a settings change rather then a move? Could the rectangle direction be expressed as a vector? Midpoint or bounding box for Square-Wave would be super useful.

moghyukon commented 8 months ago

I do not fully understand your specific problem but I also had some quirks with the square wave and its dimensions. I wanted to place mine always in the middle and the stretch a little bit but sometimes I get gaps. (not visible in print). -> A midpoint including the half length would be nice ...

Gap on left side even after proper calculation ... Bug or view problem from prusa slicer ? squarewave_gap

fullcontrol-xyz commented 8 months ago

Ah that's a really cool model and notebook!

There isn't a function for last point in list, but it will be easy for me to add and can see the value. I'll put it on the FullControl road map

For a rectangle. It is currently just a very simple function with no option to choose angle. However, if you wrap the rectangle function in a move_polar function, you can rotate about the start point and achieve what you want in one line of code.

Getting the midpoint of a list of steps is also v useful, I can see. I'll add that to the road map. I already have a function to find the bounding box data of a list of steps but it's only used behind the scenes. I can provide it to end users though. That would also allow the length to be easily calculated for a square wave in X or Y directions, but not for diagonal ones. For them, it's probably best to use a distance-between-two-points function. This is a quick function that I do use behind the scenes, so will look to release that function to the end user too, but it's also v easy to write a pythagoras function for it.

In terms of the design, there are a few things you could do to tidy it up, but it's quite nice and understandable, so nothing critical.

The following line can just be a relative point with z_clear, you don't need the move function wave2_start_point = fc.move(fc.relative_point(wave,0,0,0), fc.Vector(x=0, y=0, z=z_clear))

To get a really concise design, you could look into repeating and rotating the first layer using the move_polar function.

scamiv commented 8 months ago

Thanks for the answer. Only after the initial posting i discovered that i can use the fc.relative_point function to get the last point in a list, before i had been using list[-X] which was ugly and annoying when adding non-steps to the list. I think the documentation is a bit lacking in that regard. (maybe always encourage to use first_pint/relative_point in the examples instead of direct addressing) I have just updated the notebook to make full use of it.

Thank you for the tip with move_polar after realizing it rotates whole list i made use of it in the current design to make the "2nd layer" optional. I know this is still not very clean and will consider doing a "rewrite" at some point to make proper use of it.

I have also been wondering about doing diagonal infill, do you have a idea how this could be archived in a smart way(not drawing each line in a loop) ? Is there perhaps a way to get intersection between point lists??

edit: i played around a bit with shapely and its LineString/Polygon functions which do the job quite well,

Here is the (dirty,wip) result, it can use a points list as a bounding box and as a infill pattern: https://colab.research.google.com/gist/scamiv/f10f604b84077624a03a96f813aeecbe/infill-monotonic.ipynb

fullcontrol-xyz commented 8 months ago

Yes actually, I forgot the relative_point checks and excluded non-point objects. The documentation is quite preliminary for relative_point because it was added quite recently and is not that well tested. But the documentation referring to list[-1] has the advantage that it's using built-in python functions rather than a custom function I've written. For many people, they'd like the fact they know exactly what list[-1] means whereas the code I've written for relative_point will be doing things they might not know/want. But I will likely be using relative_point more prominently going forwards and then it will feature more in docs.

That's really cool that you got auto infill cropping! Loads of people will like that.

How much effort would it take to make your method work without requiring shapely? FullControl users are already required to have numpy, so that's not an issue really, but I try to avoid increasing the number of required packages if at all possible. It's also nice ideally, to not use numpy, but not critical at all - it would just mean that people who have learned how to use FullControl but aren't familiar with numpy can use/modify the code easier. FYI, I have got some functions in lab to check for intersection between two lines (defined by fullcontrol Points). There's a function to check in there is an intersection and also to return the point of intersection. These are not well documented yet since I have only used them a bit and they need a little more testing.

Thanks for the super interesting a valuable work!