Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stretch algorithm #94

Closed
wants to merge 15 commits into from

Conversation

@electrocbd
Copy link
Contributor

electrocbd commented May 13, 2014

This is a patch I used to fix incorrect diameters of vertical holes and, in general, insufficient inner dimensions. I created a new parameter "stretchDistance". When this parameter is zero (the default), nothing new occurs. When the parmeter is 600 - for my printer - the system increases diameters in a manner all diameters are accurate, even small ones.
The idea behind the algorithm is that the command sent to the printer is like the position of the front wheel of a bike, and the real position of the plastic is the position of the rear wheel. stretchDistance is the distance, in microns, between the front and the rear wheel. Maths : http://www.mathcurve.com/courbes2d/tractrice/tractoiredecercle.shtml

The following pictures show the effect of the stretch algorithm. A simple object with 1, 2, 3, 4, 5, 6, 7 and 8 mm holes diameter is a perfect fit for corresponding drills
stretch2
stretch1

Previous (closed) pull requests are #53 and #54

@totalretribution

This comment has been minimized.

Copy link
Contributor

totalretribution commented Jun 12, 2014

This seems to cause artifacts with certain models.
If you slice the TNut.stl using your stretch branch it creates this weird extrude on layer 42.
tnut

This is a link to the stl model that has this issue.
https://www.dropbox.com/s/btv4n3s9gnkma13/TNut.stl

@electrocbd

This comment has been minimized.

Copy link
Contributor Author

electrocbd commented Jun 12, 2014

Le 12/06/2014 18:11, totalretribution a écrit :

This seems to cause artifacts with certain models.
If you slice the TNut.stl using your stretch branch it creates this
weird extrude on layer 42.
tnut
https://cloud.githubusercontent.com/assets/3390646/3260234/d7257b00-f24b-11e3-8fc9-db8e52758b53.jpg

This is a link to the stl model that has this issue.
https://www.dropbox.com/s/btv4n3s9gnkma13/TNut.stl


Reply to this email directly or view it on GitHub
#94 (comment).

Hi
I cannot - yet - reproduce the issue with my CuraEngine settings
Can you send me the CuraEngine parameters you use? (extrusionWidth, etc.)

Thank you for testing :-)

@electrocbd

This comment has been minimized.

Copy link
Contributor Author

electrocbd commented Jun 12, 2014

Le 12/06/2014 18:11, totalretribution a écrit :

This seems to cause artifacts with certain models.
If you slice the TNut.stl using your stretch branch it creates this
weird extrude on layer 42.
tnut
https://cloud.githubusercontent.com/assets/3390646/3260234/d7257b00-f24b-11e3-8fc9-db8e52758b53.jpg

This is a link to the stl model that has this issue.
https://www.dropbox.com/s/btv4n3s9gnkma13/TNut.stl


Reply to this email directly or view it on GitHub
#94 (comment).

I got it! With 0,25mm layer height.
I will work on it next weekend

@andol

This comment has been minimized.

Copy link

andol commented Jun 12, 2014

Hi!
I would test the patch but I've compiled Cura with your CuraEngine branch and now I don't know how i can apply the "stretchDistance" parameter.
Need help :-)

thanks
andol

PS : I'm using the last issue of cura (cloned git https://github.com/daid/Cura) with debian amd_64

@electrocbd

This comment has been minimized.

Copy link
Contributor Author

electrocbd commented Jun 12, 2014

Le 12/06/2014 20:14, andol a écrit :

Hi!
I would test the patch but I've compiled Cura with your CuraEngine
branch and now I don't know how i can apply the "stretchDistance"
parameter.
Need help :-)

thanks
andol

PS : I'm using the last issue of cura (cloned git
https://github.com/daid/Cura) with debian amd_64


Reply to this email directly or view it on GitHub
#94 (comment).

Hi
I use CuraEngine alone (i.e. without Cura)
The parameter can be provided in command line, or in the "default.cfg"
configuration file in the working directory, like any CuraEngine parameter.
The following line will be correctly interpreted:

stretchDistance = 600

The higher the value, the higher the compensation. If stretchDistance =
0, the the system falls back to default CuraEngine.

Anyway, I have to look at Cura, to see how to interface it properly...

@andol

This comment has been minimized.

Copy link

andol commented Jun 12, 2014

I think that a cura's plugin will be the best I'll investigate on this way
http://wiki.ultimaker.com/How_to_write_a_Cura_plugin

@totalretribution

This comment has been minimized.

Copy link
Contributor

totalretribution commented Jun 13, 2014

@ andol
If you want to add new options to cura its quite easy. Just edit the various .py files in cura folder and add

setting('stretchDistance', 600, int, 'advanced', ('Quality')).setLabel(("Stretch Distannce in micron's"), _("Stretch Distannce in micron's")) to profile.py

and add
settings['stretchDistance'] = int(profile.getProfileSettingFloat('stretchDistance')) to sliceEngine.py

Look at my commit as an example on where to add these.
totalretribution/Cura@798ca4c

Remember though that at the moment electrocbd stretch algorithm has a fairly major bug and so I would wait until he has fixed it.

@andol

This comment has been minimized.

Copy link

andol commented Jun 13, 2014

Many thanks! I've difficulties with python :-)
I will try it, but could you tell me more about this bug? I think it's the problem of artefacts that you talk above

@electrocbd

This comment has been minimized.

Copy link
Contributor Author

electrocbd commented Jun 14, 2014

I just fixed the issue reported by total retribution
By the way, if anyone knows how to make gdb work under OpenSuse 13.1 when compiling with --std=c++11, it might help me save a lot of time :-)

andol added a commit to tetalab/Cura that referenced this pull request Jun 14, 2014
…ple, are often smaller.

electrocbd a github's user has forked CuraEngine, the C++ slicing engine used by cura to include a patch that fixes the problem.
(Ultimaker/CuraEngine#94 issuecomment-45,938,481).
With the help of totalretribution another user, changes have been made in the code of Cura to appear in the interface as the
stretchdistance with a value in microns. totalretribution/Cura@798ca4c
The installation script "package.sh" was modified to compile CuraEngine from electrocbd.

Les cotes intérieures des pieces slicées par Cura comme les trous par exemple sont souvent plus petites.
electrocbd un utilisateur de github à fait un fork de CuraEngine qui est le moteur C++ de slicing utilisé par cura pour y intégrer un patch qui corrige le problème
(Ultimaker/CuraEngine#94 (comment)).
Avec l'aide de totalretribution un autre utilisateur, des modifications ont été apportés dans le code de Cura pour apparaitre dans l'interface sous le nom de
stretchdistance avec une valeur en microns. totalretribution/Cura@798ca4c
Le script d'installation package.sh a été modifié pour compiler le CuraEngine de electrocbd.
@andol

This comment has been minimized.

Copy link

andol commented Jun 16, 2014

I don't understand, I've compiled CuraEngine with your branch and when I apply the parameter "stretchDistance = xxx" nothing happens in cura

I also tried the command : . /CuraEngine -s strentchDistance = 600 /home/user/calibrage.stl and it's the same...

 

@electrocbd

This comment has been minimized.

Copy link
Contributor Author

electrocbd commented Jun 16, 2014

Le 16/06/2014 11:31, andol a écrit :

I don't understand, I've compiled CuraEngine with your branch and when
I apply the parameter "stretchDistance = xxx" nothing happens in cura

I also tried the command : . /CuraEngine -s strentchDistance = 600
/home/user/calibrage.stl and it's the same...


Reply to this email directly or view it on GitHub
#94 (comment).

You should notice a small difference in the diameter of vertical holes
(not horizontal ones). If the diameter of horizontal holes is wrong, you
should fix the parameter filamentFlow.
If your calibration is perfect, and without the "stretch" patch,
vertical holes have insufficient diameter while horizontal holes are OK.
If you try to print the attached calibration object, the smallest hole
(1mm diameter) is closed without patch in a real print (not in the
preview) and is correct with the patch.
To be sure that you use the patch, try an insane value like
stretchDistance=10000
Not having the patch is the same as stretchDistance=0

@andol

This comment has been minimized.

Copy link

andol commented Jun 16, 2014

Ok, but you confirm that the patch was included in your fork electrocd/CuraEngine?

@BagelOrb

This comment has been minimized.

Copy link
Member

BagelOrb commented Apr 14, 2015

What's the rationale for using the bike model?

At http://www.mathcurve.com/courbes2d/tractrice/tractoiredecercle.shtml we see that a small circle will result in a weird looking flower. Why would we want such a thing?

@electrocbd

This comment has been minimized.

Copy link
Contributor Author

electrocbd commented Apr 21, 2015

circle
In this figure, P1 P2 and P3 are three successive points of the curve. C is the center of the circle which contains the 3 points, and NP is the new point, which will be used in place of P2. The distance between NP and C is sqrt(D2+S2) where D is the distance between C and P2

This operation is done for every point a the curve, in fact each point of any inner or outer wall.

@BagelOrb

This comment has been minimized.

Copy link
Member

BagelOrb commented Apr 22, 2015

Alright. That's pretty clear!

Your algorithm is symmetric. The yellow curve you plotted is rotationally symmetric because the blue curve is also rotationally symmetric. This is not true for the bike-model, however.
In the bike model the upper part of the yellow line would never be above the blue line, because any positive Y-component would also cause the back wheel to have a (smaller) positive Y-component, while the blue curve has a negative Y-component everywhere!

Your algorithm doesn't follow the bike model; however it is still quite interesting!
I will think about it.

@derekhe

This comment has been minimized.

Copy link

derekhe commented Jun 11, 2015

@BagelOrb @electrocbd
Any update about this patch? Seems this could fix some small hole problem. XY offset is bad because the outer dimension will be affected as well.

@BagelOrb

This comment has been minimized.

Copy link
Member

BagelOrb commented Jun 11, 2015

This PR will not be merged because it is not theoretically sound.

Having the very same model in higher poly causes it to be printed differently.
Lines can start to collide, with themselves and all kinds of horrible may happen.
Moreover, The circle only determines the direction in which a point is moved - even straight lines will get shifted.

See below for a little visual feedback on unwanted results.
stretch_alg_is_bs

@BagelOrb BagelOrb closed this Jun 11, 2015
@electrocbd

This comment has been minimized.

Copy link
Contributor Author

electrocbd commented Jun 11, 2015

You say that straight lines get shifted, but for straight line, the radius is infinite, and in this case, there is no correction
I stop applying correction when angles are too sharp, because in this case the circle is not a good approximation of the real movement. Your last figure is a good example, without additional points, it is very difficult to determine what should by the movement.
With the "security" I added in the source code to stop modifying the path for sharp angles, my patch is, for the moment, the one which does the best job for inner holes without affecting outer dimensions.

@derekhe

This comment has been minimized.

Copy link

derekhe commented Jun 12, 2015

@electrocbd
I'm thinking about another way. Could we only detect inside holes and stretch a certain distance if the area is small enough?
For example, we slice and find a hole in side (maybe it is not circle, can be any shape), then stretch this area to bigger.
If it is a open hole, just ignore it.

@BagelOrb

This comment has been minimized.

Copy link
Member

BagelOrb commented Jun 12, 2015

@electrocbd Yeah of course, but if the line is infinitesimally close to being a straight line it will get shifted.

I thought the bike model had some logic behind it which your current algorithm has lost. Why shouldn't we implement the algorithm I proposed (20 apr)?

@Swonkie

This comment has been minimized.

Copy link

Swonkie commented Jun 15, 2015

I am not familiar with the slicer code, but I would like to give my insight to this interesting issue. It seems to me, that it's simply a matter of ofsetting the wall paths, because the problem arises from the nozzle not being infinitely small, but having a certain diameter.

This illustration shows what I mean:
extruder

@BagelOrb

This comment has been minimized.

Copy link
Member

BagelOrb commented Jun 15, 2015

@Swonkie, nice illustration, but that is how it's done already

Quick note: my bike algorithm actually also models what has been called jerk. The stretch of the material counters the inertia of the printing head. Presumably the stretch has more effect than the overshoot by inertia, though. Otherwise the stretch hypothesis doesn't hold.

@electrocbd

This comment has been minimized.

Copy link
Contributor Author

electrocbd commented Jun 15, 2015

@BagelOrb I am afraid that your algorithm induces a distortion. The shape will be globally turned in the same direction as the head. If the head turns clockwise, the shape will be turned clockwise. It was an undesirable effect I noticed during my preliminary tests. This is why I tried to have a symmetric algorithm. This is the same with a real bike. One have to anticipate turns to have the rear wheel at the desired position.

@electrocbd

This comment has been minimized.

Copy link
Contributor Author

electrocbd commented Jun 15, 2015

@derekhe I think it is important to have a kind of symmetric approach. When printing a gear, the teeth have to be rectified the same way in the bottom and in the top. Material has to be removed from the bottom, and material has to be added to the top. A normal - not corrected - print will tend to create triangular teeth because plastic "take a shortcut"

@BagelOrb

This comment has been minimized.

Copy link
Member

BagelOrb commented Jun 15, 2015

@electrocbd Of course my algorithm introduces a distortion; one that counters distortions induced by filament stretch.

Your example is incorrect, my algorithm would not just turn it, since it would introduce new points just after the corners it moved.

The stretching of the filament is not a symmetric process. The plastic takes a shortcut from where it was to where it is now, not to where it is going to be.

This is similar with a bike. You don't anticipate the turn of the back wheel. It's hard to explain. Imagine you are riding right beside the curb and the road makes a corner right. If you anticipate the move of your back wheel your front wheel will first crash into the curb and then after that the back wheel will. When your front wheel exactly follows the curb the backwheel will grind against the curb, since a straight line from the back wheel to the front wheel intersects with the curb.

@AKSoapy29

This comment has been minimized.

Copy link

AKSoapy29 commented Apr 9, 2017

What ever happened with this? Has it been officially implemented? I'd like to use it / figure it out.

@electrocbd

This comment has been minimized.

Copy link
Contributor Author

electrocbd commented Apr 9, 2017

@DDDirk

This comment has been minimized.

Copy link

DDDirk commented Apr 23, 2017

I have a similar issue with another project, where I make a curve extra wide. And in general, I find this rather important for mechanical parts. I regularly have to adapt models to make sure the print comes out right. That's not the way it should be. Either the slicer or the firmware should handle this.

A general solution that I see is similar to BagelOrb's proposal (and drawing) of 20 april 2015. Extend both line segments of the turn a bit and connect those two vertices. So the nozzle overshoots the original vertex, then moves sideways until it crosses the extended other line segment and then continues from there.

So this:
..........
..../\....
.../  \...
../    \..

becomes that:
   _ _
...\.../....
... \./.....
..../\......
.../   \.....
../     \....

(This is for a concave turn; the printed part is shown by the dots.)

The move sideways is because of precisely the problem this is meant to deal with, namely that the nozzle drags the plastic into the turn. So now the nozzle drags it back a bit first. This prevents the problem that electrocbd mentioned on 15 june 2015, that if it is not symmetrical the shape gets turned in the direction of the turn.
Of course there should be no extrusion during the extended bit, in other words those have to be G0's. But there might still be a bit of ooze.

So there are now 3 vertices instead of 1. And there are 3 extra lines of gcode (3 G0's), which may significantly increase the size of the file, but that should not be a problem, I assume. And the maths are quite simple, so I don't think this will significantly increase calculation time.
(Btw, I assume here that it is dealt with by Cura, but it could also be done by the firmware. I don't know which is best.)

How far to extend the lines will or may depend on:

  • Nozzle size (the size of the extrusion hole). This is probably the most important factor. (My guess is the extension length should be about the nozzle size.)
  • The size of the physical nozzle (the flat bit around the hole), because that is what the plastic sticks to.
  • How sharp the curve is. For a very shallow curve it might be left out completely.
  • The speed and mass of the printhead. (In other words jerk?)
  • The 'stickyness' or viscosity (and therefore the temperature) of the material, but I think that will be less of an issue here than it normally is.
    Also, the extended paths don't have to be exacly like in the drawing. Finding out which direction is best is a matter of experimentation. With some luck, it might turn out that following the bisectrix between the two line segments gives tjhe best results. If that is true for both extensions, then only 1 vertex and 2 lines of gcode need to be added.

It becomes more complicated when turns are close to each other. For example, if it is a semi-circle that is well defined (many vertices). Or maybe it becomes simpler then. Just do it for the first turn, but not the following ones. That could at the very least be a first implementation (to experiment with).

Btw, I wonder if something similar could be done with convex turns (where the model has a sticky out bit). Especially a sharp turn, like in the drawing, tends to be rounded off by the nozzle, but this might make it more 'pointy'. Of course it shouldn't be 'blobby'. But that might be prevented by extruding less material, especially on re-entry (resuming the normal print after the extension).
This way the stickyness is put to good use (turning disadvantages into advantages is one of my great hobbies :) ).

@electrocbd

This comment has been minimized.

Copy link
Contributor Author

electrocbd commented Apr 23, 2017

I am currently using a post processing program (which translate gcode into gcode) to have good inner and outer diameters. It is not necessary to add more points, but only to move part of them without changing the extrusion amount.
So far, the best results I obtained use two consecutive algorithms. The first move each point of a curve a little to the outside of the turn, and the second move each point of any segment to the direction of wall which is on one and only one of its sides, to "push the wall".
This two algorithms, when used together, allow to have good inner and outer diameters

@DDDirk

This comment has been minimized.

Copy link

DDDirk commented Apr 24, 2017

Do I understand correctly that you now use something completely different? If so, could you share those programs? (I am rather new to github, so I don't know how you could do that.)

I assume that you do the first step only for concave turns. Or do you move all points towards the printed area? In other words, do you use an extra inset?
The second part I don't understand.

@electrocbd

This comment has been minimized.

Copy link
Contributor Author

electrocbd commented Apr 24, 2017

I just created a repository : https://github.com/electrocbd/post_stretch
There are a lot of work remaining: Translate it in English, add documentation etc.
It could be interesting to add it as a post processing option in Cura, but I have no idea how to do this.

@Ghostkeeper

This comment has been minimized.

Copy link
Member

Ghostkeeper commented May 2, 2017

If you think it works nicely and relatively bug-free, then you can consider making a pull request into our repository for the post-processing plug-in: https://github.com/nallath/PostProcessingPlugin/pulls

We'll then review the code and test it, and if it's working nicely we'll add it to the default installation of Cura for everyone to see and use.

@electrocbd

This comment has been minimized.

Copy link
Contributor Author

electrocbd commented May 8, 2017

I just created pull request "New stretch script #47". It is slower than the C++ code (python is slooow) but it gives the same results

@BagelOrb

This comment has been minimized.

Copy link
Member

BagelOrb commented Jul 25, 2017

Reopening issue because of the info in here which is still valuable for when anything like this will ever get implemented.

Search terms: [dimensional accuracy, inner outer corners holes compensate inward outward]

@BagelOrb BagelOrb reopened this Jul 25, 2017
@ChrisTerBeke

This comment has been minimized.

Copy link
Member

ChrisTerBeke commented Dec 1, 2017

Closing because super duper old. Relevant info can still be found even though it's archived.

@BagelOrb

This comment has been minimized.

Copy link
Member

BagelOrb commented Dec 1, 2017

Being old shouldn't be a criterion for closing an issue. It's about whether this issue is relevant now or in the near future.

@ChrisTerBeke

This comment has been minimized.

Copy link
Member

ChrisTerBeke commented Dec 1, 2017

It hasn't been relevant since May, but if the PR author (or someone else) would update the PR to make it relevant again for modern Cura, we can still review it of course. If no one takes that initiative, I'd call it not relevant anymore.

@BagelOrb

This comment has been minimized.

Copy link
Member

BagelOrb commented Dec 1, 2017

oh wait this is the PR... never mind.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.