I'm working on a computer science project which is a CNC plotter basically all of the methods I see for getting Gcode uses Inkscape. I have already written software to convert Normal images to black and white edges only and I have pulled the coordinates from the image. Is there any way X,Y coordinates can be used to generate Gcode ? or would i have to use Inkscape.
GCode is just instructions called where you can pass arguments.
The machine will execute the Gcode one by one and interpret it for moving his motors or do regulation depending on his firmware.
So if you want to create Gcode in python, just create a txt file and append commands.
You need to have the Gcode availables instructions of you machine first (here InkScape).
For example in Marlin:
G1 X90.6 Y13.8 ; move to 90.6mm on the X axis and 13.8mm on the Y axis
To get this file in python:
positions = [ # Get your datas of format them like this:
[90.6, 13.8], # Point 1 [x, y]
[10.6, 3.98]
]
with open("myGCode.gcode", "w") as f:
for x, y in positions:
f.write(f"G1 X{x} Y{y} ;\n")
File created content:
G1 X90.6 Y13.8 ;
G1 X10.6 Y3.98 ;
It really depends on the machine and its controller, but most of the time,
Linear interpolation like
G1 or G01 usually only needs to be specified once, like
G01 X1.0 Y2.0;
And then its linear interpolation enabled already so it can just be
X1.0 Y3.0;
...
Up to the point where you wanna go back to rapid movement (G0 G00)
Or circular interpolation with (G02, G03)
But then it's still usually just coordinates are enough after switching
to specific interpolation once.
Yet then I assume its for simple milling and more recent mills (I was trained for Haas) has some fancy pocketing functions, where you just specify
few key points for contour and they can kinda be deducted mathematically.
It would be interesting to see your program for getting a contour out of a photo.
But specifying type of interpolation between each set of coordinates is also
OK, just it might make code readability slightly more difficult.
Related
I am trying to implement some python code to separate some specific colours from an image dataset. I have separated the Cr layer from the YCbCr colour space (1-dim np array) and now I am trying to apply a curve filter similar to this in GIMP:
I did some research about the topic and found that the Bezier curve is used here.I tried to explore the curves output settings, but I couldn't understand it. I want the same effect that is applied by this curve to apply thresholding in further stages. Is there an easy way that can do it? (I am a beginner to this field)
You want something like:
pdb.gimp_drawable_curves_spline(layer,HISTOGRAM_VALUE,8,[0, 0, 0.37477797513321481, 0.12890625, 0.62344582593250431, 0.8828125, 1, 1])
Trick
You can let Gimp determine the values:
Use the GUI and apply the Curves tool on a sample:
In the image above notice the "Presets" selector at the top. Each time you apply the filter, Gimp saves the curve, and you can retrieve it with the selector. The curve is anonymous by default (only bears a time stamp) but you can also give it a name (click the + button).
These values are saved in a file in the Gimp profile. In Gimp 2.10 this file is ${Gimp profile}/filters/GimpCurvesConfig.settings. If you edit it (your editor may need to support long lines), you will see:
# settings
(GimpCurvesConfig "2019-11-08 21:57:15"
(time 1573246635)
(linear no)
(channel value)
(curve
(curve-type smooth)
(points 8 0 0 0.37477797513321481 0.12890625 0.62344582593250431 0.8828125 1 1)
(point-types 4 smooth smooth smooth smooth)
[...snip...]
The line of interest is the one that starts with (points ...). You just need to transform:
(points 8 0 0 0.37477797513321481 0.12890625 0.62344582593250431 0.8828125 1 1)
into:
... 8,[0, 0, 0.37477797513321481, 0.12890625, 0.62344582593250431, 0.8828125, 1, 1]
Can hardly be easier.
Note:
The term "Bézier curves" is quite incidental here. It is just a way for the software to smooth the curve, but you only set anchor points. The important thing is that you define a function of a channel over itself: newChannelValue=f(oldChannelvalue) and define f() not with a mathematical formula but by drawing the graph of the function.
I am plotting some points on a line in python using matplotlib, and whenever the point is at/near the boundaries of the plot the annotated text is hard to read due to overlapping axes labels and such (see screenshot below):
I'm currently using code like this to place my point annotations manually:
# add value text to x, y point
jt = x_points_to_plot # a single x-value, in this case
f = ys_func(x_points_to_plot) # a single y-value, in this case
ax.annotate(
'({}C, {:0.0f}%)'.format(jt, f), # the string text to add
xy=(jt + 1, f + 5), # offset the text from the point manually
ha='center')
Usually my points are in the middle and look acceptable, like this:
But I don't want to manually adjust the text for every point, because I have a lot of changing data and it's not where I want to spend my time; instead, I'd love to find a way to accommodate the text so it it easily readable on the plot. Maybe I could expand the plot to contain the new text, or I could move the text to a different place depending on a set of conditions about what might be near the text? I'm not sure...
I think the best answer will be one I can reuse for other projects, robust to points anywhere on the plot, and relatively easy to implement (least amount of custom functions or "hacks" that I would have to recreate for every project). Thanks a ton in advance!
Basically, i have a corpus of ~10,000 STL files, and i need to turn them all into 32x32x32 arrays of 1's and 0's (voxels)
I already have this script that turns STL files into voxels; https://github.com/rcpedersen/stl-to-voxel , but sometimes even though i specify that i need a 32x32x32 array, it will give me some huge array, and also along with being buggy, it takes FOREVER (processed ~600 files in 48 hours...)
Would it be easier to attempt to fix this script, or to write my own? It doesnt seem like voxelizing an STL would be a hard task, but I don't know any of the methods out there for this; if there are any strategies/tips, anything would be greatly appreciated.
Sorry to be a bummer, but voxelisation is actually quite a hard task. And not something Python is suitable to do quickly. Even for the simple slice/crossing test I would think a c++ implementation will beat python 1:100. I recommend libigl. Or do it on the GPU for realtime :) Look for conservative rasterization. But that is for "good" meshes that are non intersecting and closed. Otherwise it becomes a lot harder. Look for "generalized winding numbers" - also in igl.
Basicly voxelizing facet surface means separation inside form outside. It can be done in different ways: easiest way is to find signed distance from each voxel but it requeres input mesh to be closed, other way is to find winding number. You can find implemetation of both in MeshLib. Also there is python module that can help you:
pip install --upgrade pip
pip install meshlib
from meshlib import mrmeshpy as mm
# load mesh
mesh = mm.loadMesh(mm.Path("path_to_file.stl"))
mtvParams = mm.MeshToVolumeParams()
# signed will have negative values inside mesh and positive outside, but requires closed mesh
mtvParams.type = mm.MeshToVolumeParamsType.Signed
# voxels with presice distance - 3 inside, 3 - outside
mtvParams.surfaceOffset = 3
# find correct voxel size to have 32x32x32 volume
meshBox = mesh.computeBoundingBox()
boxSize = meshBox.max-meshBox.min
mtvParams.voxelSize = boxSize / 27.0
voxels = mm.meshToVolume(mesh,mtvParams)
# save voxels as tiff slices
vsParams = mm.VoxelsSaveSavingSettings()
vsParams.path = "save_voxels_dir"
vsParams.slicePlane = mm.SlicePlane.XY
mm.saveAllSlicesToImage(voxels,vsParams)
Building svg file using svgwrite-1.1.9 using polyline entities.
How can I prevent flipped output?
It seems the coordinates are messed up - vertical (y) is flipped.
Here's the code I'm using to generate the polyline:
# generate svg element
line = dwg.add(dwg.polyline(
pairs,
stroke='black', fill='blue'))
Pairs is a list of tuples in cartesian coordinates (X Y pairs):
[(2228.427, 1643.919), (2419.889, 1643.919), (2419.889, 1814.927), (2431.918, 1985.935), (2216.397, 1985.935), (2228.427, 1814.927), (2228.427, 1643.919)]
I'm using InkScape to visualize the svg output, and an in-house editor to visualize an alternate data stream; the in-house version is the correct version. I'm missing one entity.
The right entity block is rotated (in source), the left one is not (but is flipped). You can see in the svg that the entire right block is also flipped vertically, so it's above where it should be.
I haven't set any user viewport/coordinates in the SVG.
I'm pretty sure XY are the same (SVG, other).
Difference between SVG and data coordinate systems is the correct answer, I can't flag Martineau as correct (not enough rep?), but this lets me post an updated graphic.
basically I want to graph two functions
g1 = x*cos(x*pi)
g2 = 1 - 0.6x^2
and then plot the intersection, I already have a module that takes inputs close to the two lines intersections, and then converges to those points (there's four of them)
but I want to graph these two functions and their intersections using matplotlib but have no clue how. I've only graphed basic functions. Any help is greatly appreciated
Assuming you can get as far as plotting one function, with x and g1 as numpy arrays,
pylab.plot(x,g1)
just call plot again (and again) to draw any number of separate curves:
pylab.plot(x,g2)
finally display or save to a file:
pylab.show()
To indicate a special point such as an intersection, just pass in scalars for x, y and ask for a marker such 'x' or 'o' or whatever else you like.
pylab.plot(x_intersect, y_intersect, 'x', color="#80C0FF")
Alternatively, I often mark a special place along x with a vertical segment by plotting a quick little two-point data set:
pylab.plot( [x_special, x_special], [0.5, 1.9], '-b' )
I may hardcode the y values to look good on a plot for my current project, but obviously this is not reusable for other projects. Note that plot() can take ordinary python lists; no need to convert to numpy arrays.
If you can't get as far as plotting one function (just g1) then you need a basic tutorial in matplot lib, which wouldn't make a good answer here but please go visit http://matplotlib.org/ and google "matplotlib tutorial" or "matplotlib introduction".