polyhedron in openSCAD yields "No top level geometry to render" - openscad

I do not get why this polyhedron gives me a "no top level geometry to render" error. All triangles are correctly oriented, "thrown-together"-view shows only yellow outside faces. This is my code:
top_width=39;
bottom_width=51;
col_offset=6;
length=160;
height=40;
rows=10;
cols=40;
top_row_width=top_width/rows;
bottom_row_width=bottom_width/rows;
col_length=length/cols;
walls=0.4;
box();
module box(){
polyhedron(
points=[
[ // point 0
0,
0,
height
],[ // point 1
length,
0,
height
],[ // point
length,
top_width,
height
],[ // point 3
0,
top_width,
height
],[ // point 4
0,
0+col_offset,
0
],[ // point 5
length,
0+col_offset,
0
],[ // point 6
length,
bottom_width+col_offset,
0
],[ // 7
0,
bottom_width+col_offset,
0
]
],
triangles=[
[3,1,0],
[3,2,1],
[4,5,6],
[4,6,7],
[7,2,3],
[6,2,7],
[4,3,0],
[4,7,3],
[1,2,5],
[1,2,5],
[2,6,5],
[0,1,5],
[0,5,4]
]
);
}
Any hint is very appreciated, thanks in advance!

Well I'm baffled too. Latest version of OpenSCAD supports faces in place of triangles:
faces = [
[0,3,2,1],
[0,1,5,4],
[1,2,6,5],
[2,3,7,6],
[0,4,7,3],
[4,5,6,7] ]
and that renders OK.
You might try asking on the OpenSCAD forum http://forum.openscad.org/ which is more active than here.

Related

wrong background color for subsequent frame creating a GIF

I'm trying to resize a gif in a smaller version.
this is what i come up with at the moment:
from PIL import Image
def process_gif(in_path, out_path= 'out.gif', size= (32,32)):
with Image.open(in_path) as im :
images = []
durations = []
for i in range(im.n_frames - 1, -1, -1):
im.seek(i)
im.thumbnail(size, Image.Resampling.LANCZOS) # noqa
im_temp = im.copy()
images.insert(0, im_temp)
durations.append(im.info['duration'])
images[0].save(
out_path,
format='gif',
interlace=True,
save_all=True,
append_images=images[1 :],
loop=0,
duration=durations,
disposal=2,
background=(255,255,255,255),
optimize=False
)
when i try to create the gif the first frame have the correct background and the rest have isssue.
with this gif as imput in.gif
i get those frame in the images before saving: 0 1 2 3
and this is the output out.gif
spent some time figuring out where is the error with no clue, the output should have trasparent background in every frame of the GIF
P.S. i noticed imgur colored the trasparent frame, the in.gif, 0, 1, 2, 3 all have trasparent background, open with your image viewer should let you see better
After some other attemp i looked for trasparency doing print(im_temp.info) before inserting the resized image, NOTE that the cycle it's backward to solve another issue so it's last frame to first frame
{'version': b'GIF89a', 'background': 0, 'loop': 0, 'duration': 70}
{'version': b'GIF89a', 'background': 0, 'loop': 0, 'duration': 70}
{'version': b'GIF89a', 'background': 0, 'loop': 0, 'duration': 70}
{'version': b'GIF89a', 'background': 0, 'loop': 0, 'duration': 70, 'transparency': 48, 'extension': (b'NETSCAPE2.0', 219)}
from PIL import GifImagePlugin
GifImagePlugin.LOADING_STRATEGY = GifImagePlugin.LoadingStrategy.RGB_AFTER_DIFFERENT_PALETTE_ONLY
using this solved my problem

Is there a way to set two outer variable value in a test in openSCAD?

As far as I understand, openSCAD trying to be a functional language makes it unable to set an outside variable value from inside a context. eg :
(p, q) = true ? (1, 2) : (3, 4);
if (faces==4) {
p=3; q=3;
} else if (faces==6) {
p=4; q=3;
} else if (faces==8) {
p=3; q=4;
} else if (faces==12) {
p=5; q=3;
} else if (faces==20) {
p=3; q=5;
} else {
message = str("platon solid cannot have ", faces, " faces (only 4, 6, 8, 12 and 20).");
assert (false, message);
}
dihedral = 2*asin(cos(180/p)/sin(180/p)); // Won't work
In a language like python, the simple solution to such a problem would be to return a tuple. e.g.:
def platon(faces):
if faces==4: return 3, 3
if faces==6: return 4, 3
if faces==8: return 3, 4
if faces==12: return 5, 3
if faces==20: return 3, 5
raise ValueError(f"platon solid cannot have {faces} faces (only 4, 6, 8, 12 and 20)."
p, q = platon(N)
dihedral = 2*asin(cos(180/p)/sin(180/p))
But it looks like openSCAD is not able to return more that one variable at a time...
Is there a way (other than a workaround) to solve such a problem ?
Indeed:
OpenSCAD is a Functional programming language, as such variables are bound to expressions and keep a single value during their entire lifetime due to the requirements of referential transparency. In imperative languages, such as C, the same behavior is seen as constants, which are typically contrasted with normal variables.
Also note that:
OpenSCAD variables are created by a statement with a name or identifier, assignment via an expression and a semicolon. The role of arrays, found in many imperative languages, is handled in OpenSCAD via vectors.
Furthermore, conditional statements can be used to solve this specific problem, you need to make sure that there is a single assignment of the variables.
faces = 8;
vector = faces == 4 ? [3,3] : faces == 6 ? [4,3] : faces == 8 ? [3,4] : faces == 12 ? [5,3] : faces == 20 ? [3,5] : [0,0];
echo("Vector is ", vector);
if (vector[0] == 0 && vector[1] == 0) {
message = str("platon solid cannot have ", faces, " faces (only 4, 6, 8, 12 and 20).");
assert (false, message);
} else {
// do note that this is a different equation than in the example
// to demonstrate usage of both vector elements!!!
dihedral = 2*asin(cos(180/vector[0])/sin(180/vector[1])); // Will work
echo("Dihedral is ", dihedral);
}
The above results in:
Parsing design (AST generation)...
Saved backup file: C:/Users/User/Documents/OpenSCAD/backups/unsaved-backup-VmsPOXsj.scad
Compiling design (CSG Tree generation)...
ECHO: "Vector is ", [3, 4]
ECHO: "Dihedral is ", 90
Compiling design (CSG Products generation)...
Geometries in cache: 0
Geometry cache size in bytes: 0
CGAL Polyhedrons in cache: 0
CGAL cache size in bytes: 0
Compiling design (CSG Products normalization)...
Normalized tree has 1 elements!
Compile and preview finished.
Total rendering time: 0:00:00.023
When faces = 5 the script will throw the assertion:
Parsing design (AST generation)...
Saved backup file: C:/Users/User/Documents/OpenSCAD/backups/unsaved-backup-VmsPOXsj.scad
Compiling design (CSG Tree generation)...
ECHO: "Vector is ", [0, 0]
ERROR: Assertion 'false' failed: "platon solid cannot have 5 faces (only 4, 6, 8, 12 and 20)." in file openscad-2021.01, line 7
TRACE: called by 'assert' in file openscad-2021.01, line 7
TRACE: called by 'if' in file openscad-2021.01, line 5
Compiling design (CSG Products generation)...
Geometries in cache: 0
Geometry cache size in bytes: 0
CGAL Polyhedrons in cache: 0
CGAL cache size in bytes: 0
Compiling design (CSG Products normalization)...
Normalized tree has 1 elements!
Compile and preview finished.
Total rendering time: 0:00:00.051
```

Define palette color based on the range of z values from a data file

Suppose I have a data file with x y z column, which looks like:
-3.063052922487259 -3.141592741012573 401.3000000000000
-3.063052922487259 -3.063052922487259 1.290000000000000
-3.063052922487259 -2.984513103961945 0.920000000000000
-2.984513103961945 -3.141592741012573 0.100000000000000
-2.984513103961945 -3.063052922487259 10.80000000000000
-2.984513103961945 -2.984513103961945 1001.290000000000
-2.905973285436630 -2.984513103961945 514.4000000000000
-2.905973285436630 -2.905973285436630 131.0300000000000
-2.905973285436630 -2.827433466911316 129.3300000000000
The range of the values within the z column will define the color of the data points. For example, on the z column, if the value is between 0.0 and 0.3, the color of data points will be set as blue; if between 0.3 and 1, the color of data points will be set as orange; if between 400 and 1000, the color of data points will be set as navy.
So I write some code like this:
set xrange [0:15]
set yrange [0:-15]
set zrange [0:1400]
set cbrange [0.001:1400]
set palette defined ( 0 "goldenrod", 0.3 "blue", 1 "orange", 2 "cyan", 4 "yellow", 10 "green", 20 "pink", 50 'gold', 100 'purple', 400 'navy', 1000 "red")
set palette maxcolors 11
unset key
unset surface
splot "DATA.dat" using 1:2:3 with image
Which does not work. Any help?
Further update:
I really want to explain clearer why does not work, but Stack Overflow does not allow me to further explain, because they require me to have 10 reputation points in order to post an image result. So I can not post my result due to lacking of reputation. But I do modify my data set, so you can see the xy-data is equidistance now.
So I just describe the problem by words, instead of image, which is that the color box is wrong. According to my code, between 400 and 1000 should be navy (just one color). But the color box on the image shows that between 400 and 1000, there are 5 different navy colors, from shallow navy to deep navy. How can I only have one navy color between 400 and 1000 please?
The maxcolors option doesn't work properly in your case because it only discretizes the underlying color gradient. You can use the test palette command to see how your actual palette looks like:
set palette defined ( 0 "goldenrod", 0.3 "blue", 1 "orange", 2 "cyan", 4 "yellow", 10 "green", 20 "pink", 50 'gold', 100 'purple', 400 'navy', 1000 "red")
set palette maxcolors 11
test palette
You must also keep in mind, that the numbers used in the palette definition aren't absolute values on the cb-axis, but the values (in your case from 0 to 1000) are mapped to the actual cbrange (0.001 to 1400).
In order to get regions with constant color value, you do the following:
set palette defined (0 "goldenrod", \
0 "blue", 0.3 "blue", \
0.3 "orange", 1 "orange", \
1 "cyan", 2 "cyan", \
2 "yellow", 4 "yellow", \
4 "green", 10 "green", \
10 "pink", 20 "pink", \
20 "gold", 50 "gold", \
50 "purple", 400 "purple", \
400 "navy", 1000 "navy", \
1000 "red", 1400 "red")
test palette

Qt Embedded exchanged colors bits: Red and Blue

I'm using QtEmbedded (4.8.0) on an ARM display device with 16bits color depth on the framebuffer (/dev/fb0). At this scenario we are getting the colors bits RED and BLUE exchanged.
We are using the following compile flags:
./configure -embedded arm -xplatform qws/linux-arm-gnueabi-g++ -prefix /home/rchaves/Toolchain -release -opensource -shared -fast -depths 16 -largefile -no-exceptions -no-accessibility -stl -no-sql-mysql -no-sql-psql -no-sql-oci -no-sql-odbc -no-sql-tds -no-sql-db2 -no-sql-sqlite -no-sql-sqlite2 -no-sql-ibase -no-qt3support -no-xmlpatterns -no-multimedia -no-audio-backend -no-phonon-backend -no-svg -no-webkit -no-javascript-jit -no-script -no-scripttools -no-declarative -no-declarative-debug -qt-zlib -qt-libtiff -qt-libpng -qt-libmng -qt-libjpeg -no-openssl -no-nis -no-cups -iconv -no-pch -no-dbus -qt-freetype -no-opengl -qt-gfx-linuxfb -qt-kbd-linuxinput -qt-mouse-tslib -nomake demos -nomake examples
And the following parameters to execute the application:
QWS_DISPLAY=LinuxFb:/dev/fb0:depth=16 ./app -qws
Here there are the application framebuffer (samples) log:
The framebuffer device was opened successfully.
Fixed screen info:
id: DISP3 BG
smem_start: 0x93800000
smem_len: 7864320
type: 0
type_aux: 0
visual: 2
xpanstep: 1
ypanstep: 1
ywrapstep: 0
line_length: 2048
mmio_start: 0x0
mmio_len: 0
accel: 0
The framebuffer device was mapped to memory successfully.
Successfully switched to graphics mode.
Variable screen info:
xres: 1024
yres: 768
xres_virtual: 1024
yres_virtual: 3840
yoffset: 0
xoffset: 0
bits_per_pixel: 16
grayscale: 0
red: offset: 0, length: 5, msb_right: 0
green: offset: 5, length: 6, msb_right: 0
blue: offset: 11, length: 5, msb_right: 0
transp: offset: 0, length: 0, msb_right: 0
nonstd: 0
activate: 64
height: -1
width: -1
accel_flags: 0x0
pixclock: 15385
left_margin: 157
right_margin: 157
upper_margin: 16
lower_margin: 15
hsync_len: 5
vsync_len: 1
sync: 0
vmode: 0
Frame Buffer Performance test...
Average: 43020 usecs
Bandwidth: 174.338 MByte/Sec
Max. FPS: 23.245 fps
Will draw 3 rectangles on the screen,
they should be colored red, green and blue (in that order).
Done.
Better late than never. I had this exact problem with a SAM5 processor using Qt5.5.1 and the linuxfb plugin. Reconfigure or recompile the Qt5 framework will NOT solve the problem.
Apparently the LinuxFB plugin does not support the BGR format. There is an open bug tracking this issue. Check the determineFormat function in ../src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp, in which you will find out that the ImageFormats are hardcoded to **RGB no matter what kind of framebuffer info was provided.
To solve the problem, applying the patch attached to the bug may help you to resolve this issue.
I said "may" because my framebuffer driver was falsely reporting it is in the RBG format. So watch out for that. If that is the case, just hardcode the swapRgb flag until you fix your framebuffer driver.
Update: Try setting -depths generic in ./configure and run with -display linuxfb:genericcolors. This is as per this thread which discusses the problem.
Old answer: It sounds like your endian-ness of the display is swapped.
As per the documentation, you can try to pass the littleendian option to the display string. The other option is to consult the linux fb documentation about performing endian swaps.

How to create interactive chart with Rebol

I have this code to create a candlestick chart in rebol. Now I'd like to use over feel http://www.rebol.com/how-to/feel.html#section-6 to show info on each candlestick but my box is drawn with draw dialect and it doesn't seem to accept event ?
plot: [
pen green line 5x404 5x440 pen gold fill-pen 0.255.0 box 3x424 7x418 line 10x396 10x422 pen gold fill-pen 0.255.0 box 8x418 12x402 line 15x397 15x436 pen gold fill-pen 255.0.0 box 13x401 17x435 line 20x429 20x447 pen gold fill-pen 255.0.0 box 18x434 22x446 line 25x441 25x464 pen gold fill-pen 255.0.0 box 23x446 27x463 line 30x445 30x493 pen gold fill-pen 255.0.0 box 28x461 32x482 line 35x470 35x504 pen gold fill-pen 255.0.0 box 33x481 37x492 line 40x466 40x498 pen gold fill-pen 0.255.0 box 38x491 42x477
]
grid: [1100 600]
step-grid: 5
max-n-points: (grid/1 / step-grid) - 1
x-axis-border: 20
Y-margin: 10
X0: 5
grid-color: coal
main: layout [
origin 20x0
space 1x1
panel1: box 1100x580 black effect reduce [
'line-pattern 4 4
'grid 30x30 0x0 (grid-color)
'draw plot
]
panel2: box 1100x0 black
panel3: box 1100x20 black
]
view main
Here is a little expansion of my previous answer related to your chart viewer.
there are many ways you may adapt it, but it should give you some ideas into solving your problem.
rebol []
plot: []
data: reduce [ ]
refresh: func [/local clr delta prev-pos pos] [
clear plot
prev-pos: 0x300
foreach [clr delta] data [
pos: prev-pos + (delta * 0x1) + 7x0
append plot compose [
pen (clr) line (prev-pos) (pos) fill-pen (clr) pen none circle dot-size (pos)
]
prev-pos: pos
]
show panel1
]
add-data: func [i][loop i [append data reduce [(random white * .85) + (white * .15) (-20 + random 40)]] refresh]
grid: [800 600]
step-grid: 5
max-n-points: (grid/1 / step-grid) - 1
x-axis-border: 20
Y-margin: 10
X0: 5
grid-color: coal
dot-size: 3
viewer-size: 800x580
; open up console before vid window
main: layout [
origin 20x0
space 1x1
field 800
panel1: box viewer-size black rate 30 effect [
line-pattern 4 4
grid 30x30 0x0 grid-color
draw plot
] feel [
;probe first panel1
over: func [face over? offset /local d][
panel1/pane: either over? [info-pane][none]
if over? [
d: offset/x - face/offset/x - 1
d: (to-integer d / 7) * 2 + 1
either d: pick data d [
info-box/text: to-string d
][
panel1/pane: none
]
]
]
engage: func [face action event] [
switch action [
down [
drag-start: event/offset
]
up [
drag-end: event/offset
scroll-size: to-integer abs ((pick (drag-start - drag-end) 1) / 5)
]
time [
info-box/offset: event/offset - 20x20 ; the offset is the main-window origin
show main
]
]
]
]
panel2: box 800x0 black
panel3: box 800x20 black
]
insert-event-func [
either all [
event/type = 'key
none? system/view/focal-face
][
print ["shortcut: " event/key]
switch event/key [
; escape
#"^[" [quit]
; enter/return
#"^M" [print "resampling data" clear data add-data 100]
up [dot-size: dot-size + 1 show panel1]
down [dot-size: dot-size - 1 show panel1]
left [clear skip tail plot -12 clear skip tail data -2 show panel1]
right [add-data 2]
]
none
][
event
]
]
info-box: make face [
offset: 0x0
color: white * .2
size: 150x30
text: "0.0.0"
font: make font [valign: 'middle style: [bold italic]]
]
info-pane: reduce [info-box]
add-data 100
refresh
view/options main [all-over]
focus panel1
Note that as we move the mouse over the chart, we are only using the X component of the mouse to figure out what to display. Better systems are obvious, but this is sufficient to illustrate what needs to be done to receive all mouse move events and act on them.
Also note that the over feel receives Window offsets, so you must remove the face's offset to get the real face-relative coordinates.
PS: The red arrow above, is my mouse cursor.