Hi all.
I had a polyhedron generation program all running natively in openscad that
I thought was fully working, but after a big investigation I've found that
my renders are faulty to the extent that not only can't I print with
Repetier Host, but if I print in MatterControl it appears to slice and print
fine but after I've used 20grams or so of filament, my RAMPS board just
extrudes but with no more effector movement. Tracing all this back, I have
duplicate facets that I've found using either netfab or meshlab. The meshes
look perfect from the outside.
I can run a delete duplicate facets command which leaves triangles of random
orientation and then manually correct them but this is very tedious, my
latest model has about 2500 triangles. I'd like to avoid generating the
coordinate list externally to Openscad but it's quite a mission already.
Currently, if you imagine a flat underside and top side, with a math
generated mesh stretching between, then I'm calling polyhedron once for each
top/bottom segment pair and once for each level's triangle pair per side per
level. I've seen http://www.thingiverse.com/thing:8742/#files
http://www.thingiverse.com/thing:8742/#files which seems to call
polyhedron for each independent facet, but I'm concerned that my render is
possibly confusing vertices between triangles of different polyhedron calls
as being part of new co-incident triangles that I don't actually want.
rawradius=7.5;
levs=3 ; //min for test
levstep=12;
sides=4; //min for test
x_tra=16;
step=360/sides;
//translate([0,0,120]){%cube ([120,10,240],center=true);} //profile test
function completed(k)=(((k+1)/(levs+1))); //levels completed fraction of 1
function scle(l) = (sin(completed(l)65+90)); //height scale, terminate
before 90 deg
function offset(a,d)=(((rawradiusx_tra/2)-d5) -scle(d) rawradiusx_tra );
function x(a,d) =( scle(d) rawradiusx_tra * abs(sin(a/2))+offset(a,d) );
function y(a,d) =(scle(d)rawradius0.6 * sin(a)); //(sin(a))*1.4
pa=[for(lev=[0:levs+1]) for (a = [0:step:360+step])
[
a == (360+step) ? 0+offset(a,lev) +10: x(a,lev), //x
a == (360+step) ? 0 : y(a,lev), //y
levlevstep //-cos(lev9)levstep14 //
]
];
nxtl=sides+2;
for (level = [0:levs] , a = [0 : 1 : ((360/step)-1)]){side(a,level);}
for (a = [0 : 1 : ((360/step))]){bottom_top(a);}
module bottom_top(a){
polyhedron(points=pa,faces=
[[sides+1,a+1,a], //base triangles
[(levs+1)*nxtl+sides+1,a+(levs+1)*nxtl,a+(levs+1)nxtl+1] //top triangles
]);
}
module side(a,level){
polyhedron(points=pa,faces=
[[a+levelnxtl,a+(level+1)nxtl+1,a+(level+1)nxtl], //side segment
triangles
[a+levelnxtl,a+levelnxtl+1,a+(level+1)*nxtl+1]//side segment triangles
]);
}
I've since found that I can run the "invert negative shells" script on
netfab, apply and then select all, flip triangles and then apply. This gives
me a valid model. However, on a fine mesh, I suspect that the duplicate
triangles are wasting render time and I suspect my implementation is rather
cumbersome with the complete points list defined at each polyhedron call but
only a partial point order definition at each call.
Is polyhedron usage documented more fully anywhere other than on the normal
openscad wiki?
Do I have to define ALL points and point orders for a single completed
polyhedron with one polyhedron command?
At the moment, I'm trying to wrap my head around reformatting the point
order lists as multiple list comprehensions encapsulated in the point order
part of the polyhedron statement but the syntax is messing with my head.
--
View this message in context: http://forum.openscad.org/Polyhedron-issue-tp11003.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
Yes you need to define a complete solid, closed polyhedron, i.e. 2
manifold, in each call of polyhedron.
I think the only case where you can get away with parts of polygons is if
you pass them to hull, but the shape has to be convex.
On 11 January 2015 at 08:51, fluidity rael@xtra.co.nz wrote:
Hi all.
I had a polyhedron generation program all running natively in openscad that
I thought was fully working, but after a big investigation I've found that
my renders are faulty to the extent that not only can't I print with
Repetier Host, but if I print in MatterControl it appears to slice and
print
fine but after I've used 20grams or so of filament, my RAMPS board just
extrudes but with no more effector movement. Tracing all this back, I have
duplicate facets that I've found using either netfab or meshlab. The meshes
look perfect from the outside.
I can run a delete duplicate facets command which leaves triangles of
random
orientation and then manually correct them but this is very tedious, my
latest model has about 2500 triangles. I'd like to avoid generating the
coordinate list externally to Openscad but it's quite a mission already.
Currently, if you imagine a flat underside and top side, with a math
generated mesh stretching between, then I'm calling polyhedron once for
each
top/bottom segment pair and once for each level's triangle pair per side
per
level. I've seen http://www.thingiverse.com/thing:8742/#files
http://www.thingiverse.com/thing:8742/#files which seems to call
polyhedron for each independent facet, but I'm concerned that my render is
possibly confusing vertices between triangles of different polyhedron calls
as being part of new co-incident triangles that I don't actually want.
rawradius=7.5;
levs=3 ; //min for test
levstep=12;
sides=4; //min for test
x_tra=16;
step=360/sides;
//translate([0,0,120]){%cube ([120,10,240],center=true);} //profile test
function completed(k)=(((k+1)/(levs+1))); //levels completed fraction of 1
function scle(l) = (sin(completed(l)65+90)); //height scale, terminate
before 90 deg
function offset(a,d)=(((rawradiusx_tra/2)-d5) -scle(d) rawradiusx_tra
);
function x(a,d) =( scle(d) rawradiusx_tra * abs(sin(a/2))+offset(a,d) );
function y(a,d) =(scle(d)rawradius0.6 * sin(a)); //(sin(a))*1.4
pa=[for(lev=[0:levs+1]) for (a = [0:step:360+step])
[
a == (360+step) ? 0+offset(a,lev) +10: x(a,lev), //x
a == (360+step) ? 0 : y(a,lev), //y
levlevstep //-cos(lev9)levstep14 //
]
];
nxtl=sides+2;
for (level = [0:levs] , a = [0 : 1 : ((360/step)-1)]){side(a,level);}
for (a = [0 : 1 : ((360/step))]){bottom_top(a);}
module bottom_top(a){
polyhedron(points=pa,faces=
[[sides+1,a+1,a], //base triangles
[(levs+1)*nxtl+sides+1,a+(levs+1)*nxtl,a+(levs+1)nxtl+1] //top triangles
]);
}
module side(a,level){
polyhedron(points=pa,faces=
[[a+levelnxtl,a+(level+1)nxtl+1,a+(level+1)nxtl], //side segment
triangles
[a+levelnxtl,a+levelnxtl+1,a+(level+1)*nxtl+1]//side segment triangles
]);
}
I've since found that I can run the "invert negative shells" script on
netfab, apply and then select all, flip triangles and then apply. This
gives
me a valid model. However, on a fine mesh, I suspect that the duplicate
triangles are wasting render time and I suspect my implementation is rather
cumbersome with the complete points list defined at each polyhedron call
but
only a partial point order definition at each call.
Is polyhedron usage documented more fully anywhere other than on the normal
openscad wiki?
Do I have to define ALL points and point orders for a single completed
polyhedron with one polyhedron command?
At the moment, I'm trying to wrap my head around reformatting the point
order lists as multiple list comprehensions encapsulated in the point order
part of the polyhedron statement but the syntax is messing with my head.
--
View this message in context:
http://forum.openscad.org/Polyhedron-issue-tp11003.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Thanks nophead,
very inconvenient but I may work on it further if I get bored... on holiday
for a couple of weeks.
This is the finished object after repair anyway:
http://www.thingiverse.com/thing:630485
Graham
--
View this message in context: http://forum.openscad.org/Polyhedron-issue-tp11003p11005.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
Solved.
One polyhedron call with flattened concatenated point order lists for end
facets and side facets.
Now renders super fast with no need to switch to wire frame mode first.
Solution:
rawradius=7.5;
levs=19 ; //test
levstep=12;
sides=120; //test
x_tra=16;
step=360/sides;
//translate([0,0,120]){%cube ([120,10,240],center=true);} //profile test
function completed(k)=(((k+1)/(levs+1))); //levels completed fraction of 1
function scle(l) = (sin(completed(l)65+90)); //height scale, terminate
before 90 deg
function offset(a,d)=(((rawradiusx_tra/2)-d5) -scle(d) rawradiusx_tra );
function x(a,d) =( scle(d) rawradiusx_tra * abs(sin(a/2))+offset(a,d) );
function y(a,d) =(scle(d)rawradius0.6 * sin(a)); //(sin(a))*1.4
pa=[for(lev=[0:levs+1]) for (a = [0:step:360+step])
[
a == (360+step) ? 0+offset(a,lev) +10: x(a,lev), //x
a == (360+step) ? 0 : y(a,lev), //y
levlevstep //-cos(lev9)levstep14 //
]
];
nxtl=sides+2;
side_orders=[for(level=[0:levs]) for (a = [0:1:360/step-1])
[ [a+level*nxtl,a+(level+1)nxtl+1,a+(level+1)nxtl], //side
segment triangles
[a+levelnxtl,a+levelnxtl+1,a+(level+1)*nxtl+1]]
];
end_orders=[for (a = [0:1:360/step])
[[sides+1,a+1,a], // base triangles
[(levs+1)*nxtl+sides+1,a+(levs+1)*nxtl,a+(levs+1)*nxtl+1]] //top
triangles
];
function flatten(l) = [ for (a = l) for (b = a) b ] ;
eo=flatten(end_orders);
so=flatten(side_orders);
all_orders=flatten([eo,so]);
polyhedron(points=pa,faces=all_orders);
--
View this message in context: http://forum.openscad.org/Polyhedron-issue-tp11003p11006.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
Hi Graham,
Just a few comments to clear things up:
First, there’s a small bug in your last code; you forgot the -1 on line 29:
end_orders=[for (a = [0:1:360/step-1])
It looks like this just creates some degenerate (2-vertex) triangles, but it’s probably good to clean it up.
The reason why your first version failed is that, when creating a union of separate polyhedrons, it’s crucial that the vertices where they join are exactly the same. If not, small floating point differences will be preserved and cause microscopic caps which again confuses the underlying geometry engine as the geometry isn’t manifold.
You’re using the development snapshot and this is one of the remaining issues to be resolved before release. I’m not sure which version you use, but the current master should behave better than what you describe. It works perfectly for me. This behavior was updated very late december I think.
I’ll look more closely at your design later as this would be good to add to our test framework.
-Marius