|
@ -680,16 +680,32 @@ CGAL_Nef_polyhedron CGALEvaluator::evaluateCGALMesh(const PolySet &ps)
|
|||
else // not (this->is2d)
|
||||
{
|
||||
CGAL_Nef_polyhedron3 *N = NULL;
|
||||
bool plane_error = false;
|
||||
CGAL::Failure_behaviour old_behaviour = CGAL::set_error_behaviour(CGAL::THROW_EXCEPTION);
|
||||
try {
|
||||
// FIXME: Are we leaking memory for the CGAL_Polyhedron object?
|
||||
CGAL_Polyhedron *P = createPolyhedronFromPolySet(ps);
|
||||
if (P) {
|
||||
N = new CGAL_Nef_polyhedron3(*P);
|
||||
}
|
||||
CGAL_Polyhedron P;
|
||||
bool err = createPolyhedronFromPolySet(ps,P);
|
||||
if (!err) N = new CGAL_Nef_polyhedron3(P);
|
||||
}
|
||||
catch (const CGAL::Assertion_exception &e) {
|
||||
PRINTB("CGAL error in CGAL_Nef_polyhedron3(): %s", e.what());
|
||||
if (std::string(e.what()).find("Plane_constructor")!=std::string::npos) {
|
||||
if (std::string(e.what()).find("has_on")!=std::string::npos) {
|
||||
PRINT("PolySet has nonplanar faces. Attempting alternate construction");
|
||||
plane_error=true;
|
||||
}
|
||||
} else {
|
||||
PRINTB("CGAL error in CGAL_Nef_polyhedron3(): %s", e.what());
|
||||
}
|
||||
}
|
||||
if (plane_error) try {
|
||||
PolySet ps2;
|
||||
CGAL_Polyhedron P;
|
||||
tessellate_3d_faces( ps, ps2 );
|
||||
bool err = createPolyhedronFromPolySet(ps2,P);
|
||||
if (!err) N = new CGAL_Nef_polyhedron3(P);
|
||||
}
|
||||
catch (const CGAL::Assertion_exception &e) {
|
||||
PRINTB("Alternate construction failed. CGAL error in CGAL_Nef_polyhedron3(): %s", e.what());
|
||||
}
|
||||
CGAL::set_error_behaviour(old_behaviour);
|
||||
return CGAL_Nef_polyhedron(N);
|
||||
|
|
|
@ -96,6 +96,7 @@ PolySet *CGAL_Nef_polyhedron::convertToPolyset()
|
|||
}
|
||||
else if (this->dim == 3) {
|
||||
CGAL::Failure_behaviour old_behaviour = CGAL::set_error_behaviour(CGAL::THROW_EXCEPTION);
|
||||
ps = new PolySet();
|
||||
bool err = true;
|
||||
std::string errmsg("");
|
||||
CGAL_Polyhedron P;
|
||||
|
@ -107,11 +108,11 @@ PolySet *CGAL_Nef_polyhedron::convertToPolyset()
|
|||
err = true;
|
||||
errmsg = std::string(e.what());
|
||||
}
|
||||
if (!err) err = createPolySetFromPolyhedron(P, *ps);
|
||||
if (err) {
|
||||
PRINT("ERROR: CGAL NefPolyhedron->Polyhedron conversion failed.");
|
||||
if (errmsg!="") PRINTB("ERROR: %s",errmsg);
|
||||
} else {
|
||||
ps = createPolySetFromPolyhedron(P);
|
||||
delete ps; ps = NULL;
|
||||
}
|
||||
CGAL::set_error_behaviour(old_behaviour);
|
||||
}
|
||||
|
|
|
@ -8,10 +8,9 @@
|
|||
|
||||
#include <map>
|
||||
|
||||
PolySet *createPolySetFromPolyhedron(const CGAL_Polyhedron &p)
|
||||
bool createPolySetFromPolyhedron(const CGAL_Polyhedron &p, PolySet &ps)
|
||||
{
|
||||
PolySet *ps = new PolySet();
|
||||
|
||||
bool err = false;
|
||||
typedef CGAL_Polyhedron::Vertex Vertex;
|
||||
typedef CGAL_Polyhedron::Vertex_const_iterator VCI;
|
||||
typedef CGAL_Polyhedron::Facet_const_iterator FCI;
|
||||
|
@ -35,13 +34,13 @@ PolySet *createPolySetFromPolyhedron(const CGAL_Polyhedron &p)
|
|||
double x3 = CGAL::to_double(v3.point().x());
|
||||
double y3 = CGAL::to_double(v3.point().y());
|
||||
double z3 = CGAL::to_double(v3.point().z());
|
||||
ps->append_poly();
|
||||
ps->append_vertex(x1, y1, z1);
|
||||
ps->append_vertex(x2, y2, z2);
|
||||
ps->append_vertex(x3, y3, z3);
|
||||
ps.append_poly();
|
||||
ps.append_vertex(x1, y1, z1);
|
||||
ps.append_vertex(x2, y2, z2);
|
||||
ps.append_vertex(x3, y3, z3);
|
||||
} while (hc != hc_end);
|
||||
}
|
||||
return ps;
|
||||
return err;
|
||||
}
|
||||
|
||||
#undef GEN_SURFACE_DEBUG
|
||||
|
@ -127,22 +126,20 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
CGAL_Polyhedron *createPolyhedronFromPolySet(const PolySet &ps)
|
||||
bool createPolyhedronFromPolySet(const PolySet &ps, CGAL_Polyhedron &p)
|
||||
{
|
||||
CGAL_Polyhedron *P = NULL;
|
||||
bool err = false;
|
||||
CGAL::Failure_behaviour old_behaviour = CGAL::set_error_behaviour(CGAL::THROW_EXCEPTION);
|
||||
try {
|
||||
P = new CGAL_Polyhedron;
|
||||
CGAL_Build_PolySet builder(ps);
|
||||
P->delegate(builder);
|
||||
p.delegate(builder);
|
||||
}
|
||||
catch (const CGAL::Assertion_exception &e) {
|
||||
PRINTB("CGAL error in CGAL_Build_PolySet: %s", e.what());
|
||||
delete P;
|
||||
P = NULL;
|
||||
err = true;
|
||||
}
|
||||
CGAL::set_error_behaviour(old_behaviour);
|
||||
return P;
|
||||
return err;
|
||||
}
|
||||
|
||||
CGAL_Iso_cuboid_3 bounding_box( const CGAL_Nef_polyhedron3 &N )
|
||||
|
|
|
@ -2,8 +2,9 @@
|
|||
#define CGALUTILS_H_
|
||||
|
||||
#include <cgal.h>
|
||||
class PolySet *createPolySetFromPolyhedron(const CGAL_Polyhedron &p);
|
||||
CGAL_Polyhedron *createPolyhedronFromPolySet(const class PolySet &ps);
|
||||
#include "polyset.h"
|
||||
bool createPolySetFromPolyhedron(const CGAL_Polyhedron &p, PolySet &ps);
|
||||
bool createPolyhedronFromPolySet(const PolySet &ps, CGAL_Polyhedron &p);
|
||||
CGAL_Iso_cuboid_3 bounding_box( const CGAL_Nef_polyhedron3 &N );
|
||||
CGAL_Iso_rectangle_2e bounding_box( const CGAL_Nef_polyhedron2 &N );
|
||||
|
||||
|
|
|
@ -335,3 +335,178 @@ void dxf_tesselate(PolySet *ps, DxfData &dxf, double rot, Vector2d scale, bool u
|
|||
dxf.paths[path[2]].is_inner = !up;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Tessellation of 3d PolySet faces
|
||||
|
||||
This code is for tessellating the faces of a 3d PolySet, assuming that
|
||||
the faces are near-planar polygons.
|
||||
|
||||
We do the tessellation by projecting each polygon of the Polyset onto a
|
||||
2-d plane, then running a 2d tessellation algorithm on the projected 2d
|
||||
polygon. Then we project each of the newly generated 2d 'tiles' (the
|
||||
polygons used for tessellation, typically triangles) back up into 3d
|
||||
space.
|
||||
|
||||
(in reality as of writing, we dont need to do a back-projection from 2d->3d
|
||||
because the algorithm we are using doesn't create any new points, and we can
|
||||
just use a 'map' to associate 3d points with 2d points).
|
||||
|
||||
The code assumes the input polygons are simple, non-intersecting, without
|
||||
holes, without duplicate input points, and with proper orientation.
|
||||
|
||||
The purpose of this code is originally to fix github issue 349. Our CGAL
|
||||
kernel does not accept polygons for Nef_Polyhedron_3 if each of the
|
||||
points is not exactly coplanar. "Near-planar" or "Almost planar" polygons
|
||||
often occur due to rounding issues on, for example, polyhedron() input.
|
||||
By tessellating the 3d polygon into individual smaller tiles that
|
||||
are perfectly coplanar (triangles, for example), we can get CGAL to accept
|
||||
the polyhedron() input.
|
||||
*/
|
||||
|
||||
typedef enum { XYPLANE, YZPLANE, XZPLANE, NONE } projection_t;
|
||||
|
||||
// this is how we make 3d points appear as though they were 2d points to
|
||||
//the tessellation algorithm.
|
||||
Vector2d get_projected_point( Vector3d v, projection_t projection ) {
|
||||
Vector2d v2(0,0);
|
||||
if (projection==XYPLANE) { v2.x() = v.x(); v2.y() = v.y(); }
|
||||
else if (projection==XZPLANE) { v2.x() = v.x(); v2.y() = v.z(); }
|
||||
else if (projection==YZPLANE) { v2.x() = v.y(); v2.y() = v.z(); }
|
||||
return v2;
|
||||
}
|
||||
|
||||
CGAL_Point_3 cgp( Vector3d v ) { return CGAL_Point_3( v.x(), v.y(), v.z() ); }
|
||||
|
||||
/* Find a 'good' 2d projection for a given 3d polygon. the XY, YZ, or XZ
|
||||
plane. This is needed because near-planar polygons in 3d can have 'bad'
|
||||
projections into 2d. For example if the square 0,0,0 0,1,0 0,1,1 0,0,1
|
||||
is projected onto the XY plane you will not get a polygon, you wil get
|
||||
a skinny line thing. It's better to project that square onto the yz
|
||||
plane.*/
|
||||
projection_t find_good_projection( PolySet::Polygon pgon ) {
|
||||
// step 1 - find 3 non-collinear points in the input
|
||||
if (pgon.size()<3) return NONE;
|
||||
Vector3d v1,v2,v3;
|
||||
v1 = v2 = v3 = pgon[0];
|
||||
for (size_t i=0;i<pgon.size();i++) {
|
||||
if (pgon[i]!=v1) { v2=pgon[i]; break; }
|
||||
}
|
||||
if (v1==v2) return NONE;
|
||||
for (size_t i=0;i<pgon.size();i++) {
|
||||
if (!CGAL::collinear( cgp(v1), cgp(v2), cgp(pgon[i]) )) {
|
||||
v3=pgon[i]; break;
|
||||
}
|
||||
}
|
||||
if (CGAL::collinear( cgp(v1), cgp(v2), cgp(v3) ) ) return NONE;
|
||||
// step 2 - find which direction is best for projection. planes use
|
||||
// the equation ax+by+cz+d = 0. a,b, and c determine the direction the
|
||||
// plane is in. we want to find which projection of the 'normal vector'
|
||||
// would make the smallest shadow if projected onto the XY, YZ, or XZ
|
||||
// plane. 'quadrance' (distance squared) can tell this w/o using sqrt.
|
||||
CGAL::Plane_3<CGAL_Kernel3> pl( cgp(v1), cgp(v2), cgp(v3) );
|
||||
NT3 qxy = pl.a()*pl.a()+pl.b()*pl.b();
|
||||
NT3 qyz = pl.b()*pl.b()+pl.c()*pl.c();
|
||||
NT3 qxz = pl.c()*pl.c()+pl.a()*pl.a();
|
||||
NT3 min = std::min(qxy,std::min(qyz,qxz));
|
||||
if (min==qxy) return XYPLANE;
|
||||
else if (min==qyz) return YZPLANE;
|
||||
return XZPLANE;
|
||||
}
|
||||
|
||||
/* triangulate the given 3d polygon using CGAL's 2d Constrained Delaunay
|
||||
algorithm. Project the polygon's points into 2d using the given projection
|
||||
before performing the triangulation. This code assumes input polygon is
|
||||
simple, no holes, no self-intersections, no duplicate points, and is
|
||||
properly oriented. output is a sequence of 3d triangles. */
|
||||
bool triangulate_polygon( const PolySet::Polygon &pgon, std::vector<PolySet::Polygon> &triangles, projection_t projection )
|
||||
{
|
||||
bool err = false;
|
||||
CGAL::Failure_behaviour old_behaviour = CGAL::set_error_behaviour(CGAL::THROW_EXCEPTION);
|
||||
try {
|
||||
CDT cdt;
|
||||
std::vector<Vertex_handle> vhandles;
|
||||
std::map<CDTPoint,Vector3d> vertmap;
|
||||
CGAL::Orientation original_orientation;
|
||||
std::vector<CDTPoint> orienpgon;
|
||||
for (size_t i = 0; i < pgon.size(); i++) {
|
||||
Vector3d v3 = pgon.at(i);
|
||||
Vector2d v2 = get_projected_point( v3, projection );
|
||||
CDTPoint cdtpoint = CDTPoint(v2.x(),v2.y());
|
||||
vertmap[ cdtpoint ] = v3;
|
||||
Vertex_handle vh = cdt.insert( cdtpoint );
|
||||
vhandles.push_back(vh);
|
||||
orienpgon.push_back( cdtpoint );
|
||||
}
|
||||
original_orientation = CGAL::orientation_2( orienpgon.begin(),orienpgon.end() );
|
||||
for (size_t i = 0; i < vhandles.size(); i++ ) {
|
||||
int vindex1 = (i+0);
|
||||
int vindex2 = (i+1)%vhandles.size();
|
||||
cdt.insert_constraint( vhandles[vindex1], vhandles[vindex2] );
|
||||
}
|
||||
std::list<CDTPoint> list_of_seeds;
|
||||
CGAL::refine_Delaunay_mesh_2_without_edge_refinement(cdt,
|
||||
list_of_seeds.begin(), list_of_seeds.end(), DummyCriteria<CDT>());
|
||||
|
||||
CDT::Finite_faces_iterator fit;
|
||||
for( fit=cdt.finite_faces_begin(); fit!=cdt.finite_faces_end(); fit++ )
|
||||
{
|
||||
if(fit->is_in_domain()) {
|
||||
CDTPoint p1 = cdt.triangle( fit )[0];
|
||||
CDTPoint p2 = cdt.triangle( fit )[1];
|
||||
CDTPoint p3 = cdt.triangle( fit )[2];
|
||||
Vector3d v1 = vertmap[p1];
|
||||
Vector3d v2 = vertmap[p2];
|
||||
Vector3d v3 = vertmap[p3];
|
||||
PolySet::Polygon pgon;
|
||||
if (CGAL::orientation(p1,p2,p3)==original_orientation) {
|
||||
pgon.push_back(v1);
|
||||
pgon.push_back(v2);
|
||||
pgon.push_back(v3);
|
||||
} else {
|
||||
pgon.push_back(v3);
|
||||
pgon.push_back(v2);
|
||||
pgon.push_back(v1);
|
||||
}
|
||||
triangles.push_back( pgon );
|
||||
}
|
||||
}
|
||||
} catch (const CGAL::Assertion_exception &e) {
|
||||
PRINTB("CGAL error in dxftess triangulate_polygon: %s", e.what());
|
||||
err = true;
|
||||
}
|
||||
CGAL::set_error_behaviour(old_behaviour);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Given a 3d PolySet with 'near planar' polygonal faces, Tessellate the
|
||||
faces. As of writing, our only tessellation method is Triangulation
|
||||
using CGAL's Constrained Delaunay algorithm. This code assumes the input
|
||||
polyset has simple polygon faces with no holes, no self intersections, no
|
||||
duplicate points, and proper orientation. */
|
||||
void tessellate_3d_faces( const PolySet &inps, PolySet &outps ) {
|
||||
for (size_t i = 0; i < inps.polygons.size(); i++) {
|
||||
const PolySet::Polygon pgon = inps.polygons[i];
|
||||
if (pgon.size()<3) {
|
||||
PRINT("WARNING: PolySet has polygon with <3 points");
|
||||
continue;
|
||||
}
|
||||
projection_t goodproj = find_good_projection( pgon );
|
||||
if (goodproj==NONE) {
|
||||
PRINT("WARNING: PolySet has degenerate polygon");
|
||||
continue;
|
||||
}
|
||||
std::vector<PolySet::Polygon> triangles;
|
||||
bool err = triangulate_polygon( pgon, triangles, goodproj );
|
||||
if (!err) for (size_t j=0;j<triangles.size();j++) {
|
||||
PolySet::Polygon t = triangles[j];
|
||||
outps.append_poly();
|
||||
outps.append_vertex(t[0].x(),t[0].y(),t[0].z());
|
||||
outps.append_vertex(t[1].x(),t[1].y(),t[1].z());
|
||||
outps.append_vertex(t[2].x(),t[2].y(),t[2].z());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// End of PolySet face tessellation code
|
||||
|
||||
|
|
|
@ -7,5 +7,6 @@ class DxfData;
|
|||
class PolySet;
|
||||
void dxf_tesselate(PolySet *ps, DxfData &dxf, double rot, Vector2d scale, bool up, bool do_triangle_splitting, double h);
|
||||
void dxf_border_to_ps(PolySet *ps, const DxfData &dxf);
|
||||
void tessellate_3d_faces( const PolySet &inps, PolySet &outps );
|
||||
|
||||
#endif
|
||||
|
|
|
@ -284,7 +284,9 @@ PolySet *ImportNode::evaluate_polyset(class PolySetEvaluator *) const
|
|||
file >> poly;
|
||||
file.close();
|
||||
|
||||
p = createPolySetFromPolyhedron(poly);
|
||||
p = new PolySet();
|
||||
bool err = createPolySetFromPolyhedron(poly, *p);
|
||||
if (err) delete p;
|
||||
}
|
||||
#else
|
||||
PRINT("WARNING: OFF import requires CGAL.");
|
||||
|
|
|
@ -26,7 +26,7 @@ public:
|
|||
void append_vertex(double x, double y, double z = 0.0);
|
||||
void insert_vertex(double x, double y, double z = 0.0);
|
||||
size_t memsize() const;
|
||||
|
||||
|
||||
BoundingBox getBoundingBox() const;
|
||||
|
||||
#define CSGMODE_DIFFERENCE_FLAG 0x10
|
||||
|
|
|
@ -103,7 +103,7 @@ public:
|
|||
double fn, fs, fa;
|
||||
primitive_type_e type;
|
||||
int convexity;
|
||||
Value points, paths, triangles;
|
||||
Value points, paths, faces;
|
||||
virtual PolySet *evaluate_polyset(class PolySetEvaluator *) const;
|
||||
};
|
||||
|
||||
|
@ -156,7 +156,7 @@ AbstractNode *PrimitiveModule::instantiate(const Context *ctx, const ModuleInsta
|
|||
args += Assignment("h", NULL), Assignment("r1", NULL), Assignment("r2", NULL), Assignment("center", NULL);
|
||||
break;
|
||||
case POLYHEDRON:
|
||||
args += Assignment("points", NULL), Assignment("triangles", NULL), Assignment("convexity", NULL);
|
||||
args += Assignment("points", NULL), Assignment("triangles", NULL), Assignment("convexity", NULL), Assignment("faces", NULL);
|
||||
break;
|
||||
case SQUARE:
|
||||
args += Assignment("size", NULL), Assignment("center", NULL);
|
||||
|
@ -235,7 +235,11 @@ AbstractNode *PrimitiveModule::instantiate(const Context *ctx, const ModuleInsta
|
|||
|
||||
if (type == POLYHEDRON) {
|
||||
node->points = c.lookup_variable("points");
|
||||
node->triangles = c.lookup_variable("triangles");
|
||||
node->faces = c.lookup_variable("faces");
|
||||
if (node->faces.type() == Value::UNDEFINED) {
|
||||
// backwards compatable
|
||||
node->faces = c.lookup_variable("triangles");
|
||||
}
|
||||
}
|
||||
|
||||
if (type == SQUARE) {
|
||||
|
@ -480,11 +484,11 @@ sphere_next_r2:
|
|||
if (this->type == POLYHEDRON)
|
||||
{
|
||||
p->convexity = this->convexity;
|
||||
for (size_t i=0; i<this->triangles.toVector().size(); i++)
|
||||
for (size_t i=0; i<this->faces.toVector().size(); i++)
|
||||
{
|
||||
p->append_poly();
|
||||
for (size_t j=0; j<this->triangles.toVector()[i].toVector().size(); j++) {
|
||||
size_t pt = this->triangles.toVector()[i].toVector()[j].toDouble();
|
||||
for (size_t j=0; j<this->faces.toVector()[i].toVector().size(); j++) {
|
||||
size_t pt = this->faces.toVector()[i].toVector()[j].toDouble();
|
||||
if (pt < this->points.toVector().size()) {
|
||||
double px, py, pz;
|
||||
if (this->points.toVector()[pt].getVec3(px, py, pz))
|
||||
|
@ -610,7 +614,7 @@ std::string PrimitiveNode::toString() const
|
|||
break;
|
||||
case POLYHEDRON:
|
||||
stream << "(points = " << this->points
|
||||
<< ", triangles = " << this->triangles
|
||||
<< ", faces = " << this->faces
|
||||
<< ", convexity = " << this->convexity << ")";
|
||||
break;
|
||||
case SQUARE:
|
||||
|
|
|
@ -0,0 +1,157 @@
|
|||
// Used to cause issue #349
|
||||
|
||||
// Very slightly non-planar polyhedron
|
||||
polyhedron(faces=[[3,2,1,0],[7,6,5,4],[0,1,6,7],[1,2,5,6],[2,3,4,5],[3,0,7,4]],
|
||||
points=[
|
||||
[0.0174497,-0.0174524,0.999695],
|
||||
[1.0173,-0.0174524,0.982243],
|
||||
[1.0176,0.982395,0.999693],
|
||||
[0.0177543,0.982395,1.01715],
|
||||
[0.000304586,0.999848,0.0174497],
|
||||
[1.00015,0.999848,-0.00000265809],
|
||||
[0.999848,-0.0000000000000271051,-0.0174524],
|
||||
[0,0,0]]);
|
||||
|
||||
// Really non-planar polyhedron
|
||||
translate([2,0,0]) polyhedron(faces=[[3,2,1,0],[7,6,5,4],[0,1,6,7],[1,2,5,6],[2,3,4,5],[3,0,7,4]],
|
||||
points=[
|
||||
[0,0,1],
|
||||
[1,0.2,1],
|
||||
[1,1,1],
|
||||
[0,1,1],
|
||||
[0,1,0],
|
||||
[1,1,0],
|
||||
[1,0,0],
|
||||
[0,0,0]]);
|
||||
|
||||
// Real-world example: truncated icosidodecahedron
|
||||
translate([4.5,0.5,0.5]) scale(0.02) polyhedron(points = [
|
||||
[-10., -13.090169943749475, -34.270509831248425],
|
||||
[-10., -13.090169943749475, 34.270509831248425],
|
||||
[-10., 13.090169943749475, -34.270509831248425],
|
||||
[-10., 13.090169943749475, 34.270509831248425],
|
||||
[-5., -5., -37.3606797749979], [-5., -5., 37.3606797749979],
|
||||
[-5., 5., -37.3606797749979], [-5., 5., 37.3606797749979],
|
||||
[-5., -37.3606797749979, -5.], [-5., -37.3606797749979, 5.],
|
||||
[-5., -21.18033988749895, -31.18033988749895],
|
||||
[-5., -21.18033988749895, 31.18033988749895], [-5., 37.3606797749979, -5.],
|
||||
[-5., 37.3606797749979, 5.], [-5., 21.18033988749895, -31.18033988749895],
|
||||
[-5., 21.18033988749895, 31.18033988749895], [5., -5., -37.3606797749979],
|
||||
[5., -5., 37.3606797749979], [5., 5., -37.3606797749979],
|
||||
[5., 5., 37.3606797749979], [5., -37.3606797749979, -5.],
|
||||
[5., -37.3606797749979, 5.], [5., -21.18033988749895, -31.18033988749895],
|
||||
[5., -21.18033988749895, 31.18033988749895], [5., 37.3606797749979, -5.],
|
||||
[5., 37.3606797749979, 5.], [5., 21.18033988749895, -31.18033988749895],
|
||||
[5., 21.18033988749895, 31.18033988749895], [10., -13.090169943749475,
|
||||
-34.270509831248425], [10., -13.090169943749475, 34.270509831248425],
|
||||
[10., 13.090169943749475, -34.270509831248425],
|
||||
[10., 13.090169943749475, 34.270509831248425],
|
||||
[-34.270509831248425, -10., -13.090169943749475],
|
||||
[-34.270509831248425, -10., 13.090169943749475],
|
||||
[-34.270509831248425, 10., -13.090169943749475],
|
||||
[-34.270509831248425, 10., 13.090169943749475],
|
||||
[-29.270509831248425, -18.090169943749473, -16.18033988749895],
|
||||
[-29.270509831248425, -18.090169943749473, 16.18033988749895],
|
||||
[-29.270509831248425, 18.090169943749473, -16.18033988749895],
|
||||
[-29.270509831248425, 18.090169943749473, 16.18033988749895],
|
||||
[-18.090169943749473, -16.18033988749895, -29.270509831248425],
|
||||
[-18.090169943749473, -16.18033988749895, 29.270509831248425],
|
||||
[-18.090169943749473, 16.18033988749895, -29.270509831248425],
|
||||
[-18.090169943749473, 16.18033988749895, 29.270509831248425],
|
||||
[-13.090169943749475, -34.270509831248425, -10.],
|
||||
[-13.090169943749475, -34.270509831248425, 10.],
|
||||
[-13.090169943749475, -24.270509831248425, -26.18033988749895],
|
||||
[-13.090169943749475, -24.270509831248425, 26.18033988749895],
|
||||
[-13.090169943749475, 24.270509831248425, -26.18033988749895],
|
||||
[-13.090169943749475, 24.270509831248425, 26.18033988749895],
|
||||
[-13.090169943749475, 34.270509831248425, -10.],
|
||||
[-13.090169943749475, 34.270509831248425, 10.],
|
||||
[-26.18033988749895, -13.090169943749475, -24.270509831248425],
|
||||
[-26.18033988749895, -13.090169943749475, 24.270509831248425],
|
||||
[-26.18033988749895, 13.090169943749475, -24.270509831248425],
|
||||
[-26.18033988749895, 13.090169943749475, 24.270509831248425],
|
||||
[-37.3606797749979, -5., -5.], [-37.3606797749979, -5., 5.],
|
||||
[-37.3606797749979, 5., -5.], [-37.3606797749979, 5., 5.],
|
||||
[-16.18033988749895, -29.270509831248425, -18.090169943749473],
|
||||
[-16.18033988749895, -29.270509831248425, 18.090169943749473],
|
||||
[-16.18033988749895, 29.270509831248425, -18.090169943749473],
|
||||
[-16.18033988749895, 29.270509831248425, 18.090169943749473],
|
||||
[-31.18033988749895, -5., -21.18033988749895],
|
||||
[-31.18033988749895, -5., 21.18033988749895],
|
||||
[-31.18033988749895, 5., -21.18033988749895],
|
||||
[-31.18033988749895, 5., 21.18033988749895],
|
||||
[-21.18033988749895, -31.18033988749895, -5.],
|
||||
[-21.18033988749895, -31.18033988749895, 5.],
|
||||
[-21.18033988749895, 31.18033988749895, -5.],
|
||||
[-21.18033988749895, 31.18033988749895, 5.],
|
||||
[-24.270509831248425, -26.18033988749895, -13.090169943749475],
|
||||
[-24.270509831248425, -26.18033988749895, 13.090169943749475],
|
||||
[-24.270509831248425, 26.18033988749895, -13.090169943749475],
|
||||
[-24.270509831248425, 26.18033988749895, 13.090169943749475],
|
||||
[16.18033988749895, -29.270509831248425, -18.090169943749473],
|
||||
[16.18033988749895, -29.270509831248425, 18.090169943749473],
|
||||
[16.18033988749895, 29.270509831248425, -18.090169943749473],
|
||||
[16.18033988749895, 29.270509831248425, 18.090169943749473],
|
||||
[24.270509831248425, -26.18033988749895, -13.090169943749475],
|
||||
[24.270509831248425, -26.18033988749895, 13.090169943749475],
|
||||
[24.270509831248425, 26.18033988749895, -13.090169943749475],
|
||||
[24.270509831248425, 26.18033988749895, 13.090169943749475],
|
||||
[37.3606797749979, -5., -5.], [37.3606797749979, -5., 5.],
|
||||
[37.3606797749979, 5., -5.], [37.3606797749979, 5., 5.],
|
||||
[21.18033988749895, -31.18033988749895, -5.],
|
||||
[21.18033988749895, -31.18033988749895, 5.],
|
||||
[21.18033988749895, 31.18033988749895, -5.],
|
||||
[21.18033988749895, 31.18033988749895, 5.],
|
||||
[13.090169943749475, -34.270509831248425, -10.],
|
||||
[13.090169943749475, -34.270509831248425, 10.],
|
||||
[13.090169943749475, -24.270509831248425, -26.18033988749895],
|
||||
[13.090169943749475, -24.270509831248425, 26.18033988749895],
|
||||
[13.090169943749475, 24.270509831248425, -26.18033988749895],
|
||||
[13.090169943749475, 24.270509831248425, 26.18033988749895],
|
||||
[13.090169943749475, 34.270509831248425, -10.],
|
||||
[13.090169943749475, 34.270509831248425, 10.],
|
||||
[26.18033988749895, -13.090169943749475, -24.270509831248425],
|
||||
[26.18033988749895, -13.090169943749475, 24.270509831248425],
|
||||
[26.18033988749895, 13.090169943749475, -24.270509831248425],
|
||||
[26.18033988749895, 13.090169943749475, 24.270509831248425],
|
||||
[31.18033988749895, -5., -21.18033988749895],
|
||||
[31.18033988749895, -5., 21.18033988749895],
|
||||
[31.18033988749895, 5., -21.18033988749895],
|
||||
[31.18033988749895, 5., 21.18033988749895],
|
||||
[18.090169943749473, -16.18033988749895, -29.270509831248425],
|
||||
[18.090169943749473, -16.18033988749895, 29.270509831248425],
|
||||
[18.090169943749473, 16.18033988749895, -29.270509831248425],
|
||||
[18.090169943749473, 16.18033988749895, 29.270509831248425],
|
||||
[29.270509831248425, -18.090169943749473, -16.18033988749895],
|
||||
[29.270509831248425, -18.090169943749473, 16.18033988749895],
|
||||
[29.270509831248425, 18.090169943749473, -16.18033988749895],
|
||||
[29.270509831248425, 18.090169943749473, 16.18033988749895],
|
||||
[34.270509831248425, -10., -13.090169943749475],
|
||||
[34.270509831248425, -10., 13.090169943749475],
|
||||
[34.270509831248425, 10., -13.090169943749475],
|
||||
[34.270509831248425, 10., 13.090169943749475]],faces =
|
||||
[[41, 53, 65, 67, 55, 43, 3, 7, 5, 1], [100, 104, 106, 102, 110, 30, 18, 16,
|
||||
28, 108], [11, 1, 5, 17, 29, 23], [18, 30, 26, 14, 2, 6],
|
||||
[33, 37, 73, 69, 68, 72, 36, 32, 56, 57], [91, 90, 82, 114, 118, 86, 87,
|
||||
119, 115, 83], [81, 113, 117, 85, 84, 116, 112, 80, 88, 89],
|
||||
[59, 58, 34, 38, 74, 70, 71, 75, 39, 35], [0, 10, 22, 28, 16, 4],
|
||||
[15, 27, 31, 19, 7, 3], [64, 52, 40, 0, 4, 6, 2, 42, 54, 66],
|
||||
[19, 31, 111, 103, 107, 105, 101, 109, 29, 17], [96, 110, 102, 114, 82, 78],
|
||||
[53, 41, 47, 61, 73, 37], [43, 49, 15, 3], [94, 108, 28, 22],
|
||||
[23, 29, 109, 95], [2, 14, 48, 42], [36, 72, 60, 46, 40, 52],
|
||||
[79, 83, 115, 103, 111, 97], [69, 45, 9, 8, 44, 68],
|
||||
[24, 98, 90, 91, 99, 25], [77, 95, 109, 101, 113, 81],
|
||||
[42, 48, 62, 74, 38, 54], [40, 46, 10, 0], [97, 111, 31, 27],
|
||||
[44, 8, 20, 92, 76, 94, 22, 10, 46, 60], [63, 51, 13, 25, 99, 79, 97, 27,
|
||||
15, 49], [26, 30, 110, 96], [1, 11, 47, 41], [55, 39, 75, 63, 49, 43],
|
||||
[80, 112, 100, 108, 94, 76], [48, 14, 26, 96, 78, 98, 24, 12, 50, 62],
|
||||
[61, 47, 11, 23, 95, 77, 93, 21, 9, 45], [71, 70, 50, 12, 13, 51],
|
||||
[93, 89, 88, 92, 20, 21], [102, 106, 118, 114], [65, 53, 37, 33],
|
||||
[74, 62, 50, 70], [77, 81, 89, 93], [101, 105, 117, 113], [66, 54, 38, 34],
|
||||
[73, 61, 45, 69], [78, 82, 90, 98], [32, 36, 52, 64], [115, 119, 107, 103],
|
||||
[92, 88, 80, 76], [71, 51, 63, 75], [56, 32, 64, 66, 34, 58],
|
||||
[107, 119, 87, 85, 117, 105], [35, 39, 55, 67], [112, 116, 104, 100],
|
||||
[99, 91, 83, 79], [68, 44, 60, 72], [57, 59, 35, 67, 65, 33],
|
||||
[116, 84, 86, 118, 106, 104], [4, 16, 18, 6], [7, 19, 17, 5],
|
||||
[12, 24, 25, 13], [9, 21, 20, 8], [56, 58, 59, 57], [85, 87, 86, 84]]
|
||||
);
|
|
@ -831,8 +831,8 @@ list(APPEND DUMPTEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/escape-test
|
|||
${CMAKE_SOURCE_DIR}/../testdata/scad/misc/localfiles_dir/localfiles-compatibility-test.scad
|
||||
${CMAKE_SOURCE_DIR}/../testdata/scad/misc/allexpressions.scad
|
||||
${CMAKE_SOURCE_DIR}/../testdata/scad/misc/allfunctions.scad
|
||||
${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/stl-cgal-convert_to_Polyhedron-crash.scad
|
||||
${CMAKE_SOURCE_DIR}/../testdata/scad/misc/allmodules.scad)
|
||||
${CMAKE_SOURCE_DIR}/../testdata/scad/misc/allmodules.scad
|
||||
${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/stl-cgal-convert_to_Polyhedron-crash.scad)
|
||||
|
||||
list(APPEND CGALPNGTEST_FILES ${FEATURES_FILES} ${SCAD_DXF_FILES} ${EXAMPLE_FILES})
|
||||
list(APPEND CGALPNGTEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/include-tests.scad
|
||||
|
|
After Width: | Height: | Size: 8.8 KiB |
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 5.4 KiB |
|
@ -26,7 +26,7 @@ group() {
|
|||
cube(size = [1, 1, 1], center = false);
|
||||
sphere($fn = 0, $fa = 12, $fs = 2, r = 1);
|
||||
cylinder($fn = 0, $fa = 12, $fs = 2, h = 1, r1 = 1, r2 = 1, center = false);
|
||||
polyhedron(points = undef, triangles = undef, convexity = 1);
|
||||
polyhedron(points = undef, faces = undef, convexity = 1);
|
||||
square(size = [1, 1], center = false);
|
||||
circle($fn = 0, $fa = 12, $fs = 2, r = 1);
|
||||
polygon(points = undef, paths = undef, convexity = 1);
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
group() {
|
||||
polyhedron(points = [[10, 0, 0], [0, 10, 0], [-10, 0, 0], [0, -10, 0], [0, 0, 10]], triangles = [[0, 1, 2, 3], [4, 1, 0], [4, 2, 1], [4, 3, 2], [4, 0, 3]], convexity = 1);
|
||||
polyhedron(points = [[10, 0, 0], [0, 10, 0], [-10, 0, 0], [0, -10, 0], [0, 0, 10]], faces = [[0, 1, 2, 3], [4, 1, 0], [4, 2, 1], [4, 3, 2], [4, 0, 3]], convexity = 1);
|
||||
}
|
||||
|
|
|
@ -1,28 +1,28 @@
|
|||
group() {
|
||||
group() {
|
||||
polyhedron(points = [[1, 0, 0], [-1, 0, 0], [0, 1, 0], [0, -1, 0], [0, 0, 1], [0, 0, -1]], triangles = [[0, 4, 2], [0, 2, 5], [0, 3, 4], [0, 5, 3], [1, 2, 4], [1, 5, 2], [1, 4, 3], [1, 3, 5]], convexity = 1);
|
||||
polyhedron(points = [[1, 0, 0], [-1, 0, 0], [0, 1, 0], [0, -1, 0], [0, 0, 1], [0, 0, -1]], faces = [[0, 4, 2], [0, 2, 5], [0, 3, 4], [0, 5, 3], [1, 2, 4], [1, 5, 2], [1, 4, 3], [1, 3, 5]], convexity = 1);
|
||||
multmatrix([[1, 0, 0, 2], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
|
||||
polyhedron(points = [[1, 0, 0], [-1, 0, 0], [0, 1, 0], [0, -1, 0], [0, 0, 1], [0, 0, -1]], triangles = [[0, 4, 2], [0, 2, 5], [0, 3, 4], [0, 5, 3], [1, 2, 4], [1, 5, 2], [1, 3, 4], [1, 3, 5]], convexity = 1);
|
||||
polyhedron(points = [[1, 0, 0], [-1, 0, 0], [0, 1, 0], [0, -1, 0], [0, 0, 1], [0, 0, -1]], faces = [[0, 4, 2], [0, 2, 5], [0, 3, 4], [0, 5, 3], [1, 2, 4], [1, 5, 2], [1, 3, 4], [1, 3, 5]], convexity = 1);
|
||||
}
|
||||
multmatrix([[1, 0, 0, 4], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
|
||||
polyhedron(points = [[1, 0, 0], [-1, 0, 0], [0, 1, 0], [0, -1, 0], [0, 0, 1], [0, 0, -1]], triangles = [[0, 2, 4], [0, 5, 2], [0, 4, 3], [0, 3, 5], [1, 4, 2], [1, 2, 5], [1, 3, 4], [1, 5, 3]], convexity = 1);
|
||||
polyhedron(points = [[1, 0, 0], [-1, 0, 0], [0, 1, 0], [0, -1, 0], [0, 0, 1], [0, 0, -1]], faces = [[0, 2, 4], [0, 5, 2], [0, 4, 3], [0, 3, 5], [1, 4, 2], [1, 2, 5], [1, 3, 4], [1, 5, 3]], convexity = 1);
|
||||
}
|
||||
multmatrix([[1, 0, 0, 6], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
|
||||
polyhedron(points = [[-0.8, -0.8, -0.8], [0, 0, -0.8], [0.8, -0.8, -0.8], [0.8, 0.8, -0.8], [-0.8, 0.8, -0.8], [-0.8, -0.8, 0.8], [0, 0, 0.8], [0.8, -0.8, 0.8], [0.8, 0.8, 0.8], [-0.8, 0.8, 0.8]], triangles = [[0, 1, 2, 3, 4], [5, 6, 1, 0], [6, 7, 2, 1], [7, 8, 3, 2], [8, 9, 4, 3], [9, 5, 0, 4], [9, 8, 7, 6, 5]], convexity = 2);
|
||||
polyhedron(points = [[-0.8, -0.8, -0.8], [0, 0, -0.8], [0.8, -0.8, -0.8], [0.8, 0.8, -0.8], [-0.8, 0.8, -0.8], [-0.8, -0.8, 0.8], [0, 0, 0.8], [0.8, -0.8, 0.8], [0.8, 0.8, 0.8], [-0.8, 0.8, 0.8]], faces = [[0, 1, 2, 3, 4], [5, 6, 1, 0], [6, 7, 2, 1], [7, 8, 3, 2], [8, 9, 4, 3], [9, 5, 0, 4], [9, 8, 7, 6, 5]], convexity = 2);
|
||||
}
|
||||
}
|
||||
multmatrix([[1, 0, 0, 0], [0, 1, 0, 2], [0, 0, 1, 0], [0, 0, 0, 1]]) {
|
||||
difference() {
|
||||
group() {
|
||||
polyhedron(points = [[1, 0, 0], [-1, 0, 0], [0, 1, 0], [0, -1, 0], [0, 0, 1], [0, 0, -1]], triangles = [[0, 4, 2], [0, 2, 5], [0, 3, 4], [0, 5, 3], [1, 2, 4], [1, 5, 2], [1, 4, 3], [1, 3, 5]], convexity = 1);
|
||||
polyhedron(points = [[1, 0, 0], [-1, 0, 0], [0, 1, 0], [0, -1, 0], [0, 0, 1], [0, 0, -1]], faces = [[0, 4, 2], [0, 2, 5], [0, 3, 4], [0, 5, 3], [1, 2, 4], [1, 5, 2], [1, 4, 3], [1, 3, 5]], convexity = 1);
|
||||
multmatrix([[1, 0, 0, 2], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
|
||||
polyhedron(points = [[1, 0, 0], [-1, 0, 0], [0, 1, 0], [0, -1, 0], [0, 0, 1], [0, 0, -1]], triangles = [[0, 4, 2], [0, 2, 5], [0, 3, 4], [0, 5, 3], [1, 2, 4], [1, 5, 2], [1, 3, 4], [1, 3, 5]], convexity = 1);
|
||||
polyhedron(points = [[1, 0, 0], [-1, 0, 0], [0, 1, 0], [0, -1, 0], [0, 0, 1], [0, 0, -1]], faces = [[0, 4, 2], [0, 2, 5], [0, 3, 4], [0, 5, 3], [1, 2, 4], [1, 5, 2], [1, 3, 4], [1, 3, 5]], convexity = 1);
|
||||
}
|
||||
multmatrix([[1, 0, 0, 4], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
|
||||
polyhedron(points = [[1, 0, 0], [-1, 0, 0], [0, 1, 0], [0, -1, 0], [0, 0, 1], [0, 0, -1]], triangles = [[0, 2, 4], [0, 5, 2], [0, 4, 3], [0, 3, 5], [1, 4, 2], [1, 2, 5], [1, 3, 4], [1, 5, 3]], convexity = 1);
|
||||
polyhedron(points = [[1, 0, 0], [-1, 0, 0], [0, 1, 0], [0, -1, 0], [0, 0, 1], [0, 0, -1]], faces = [[0, 2, 4], [0, 5, 2], [0, 4, 3], [0, 3, 5], [1, 4, 2], [1, 2, 5], [1, 3, 4], [1, 5, 3]], convexity = 1);
|
||||
}
|
||||
multmatrix([[1, 0, 0, 6], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
|
||||
polyhedron(points = [[-0.8, -0.8, -0.8], [0, 0, -0.8], [0.8, -0.8, -0.8], [0.8, 0.8, -0.8], [-0.8, 0.8, -0.8], [-0.8, -0.8, 0.8], [0, 0, 0.8], [0.8, -0.8, 0.8], [0.8, 0.8, 0.8], [-0.8, 0.8, 0.8]], triangles = [[0, 1, 2, 3, 4], [5, 6, 1, 0], [6, 7, 2, 1], [7, 8, 3, 2], [8, 9, 4, 3], [9, 5, 0, 4], [9, 8, 7, 6, 5]], convexity = 2);
|
||||
polyhedron(points = [[-0.8, -0.8, -0.8], [0, 0, -0.8], [0.8, -0.8, -0.8], [0.8, 0.8, -0.8], [-0.8, 0.8, -0.8], [-0.8, -0.8, 0.8], [0, 0, 0.8], [0.8, -0.8, 0.8], [0.8, 0.8, 0.8], [-0.8, 0.8, 0.8]], faces = [[0, 1, 2, 3, 4], [5, 6, 1, 0], [6, 7, 2, 1], [7, 8, 3, 2], [8, 9, 4, 3], [9, 5, 0, 4], [9, 8, 7, 6, 5]], convexity = 2);
|
||||
}
|
||||
}
|
||||
multmatrix([[1, 0, 0, 3], [0, 1, 0, 0], [0, 0, 1, 2], [0, 0, 0, 1]]) {
|
||||
|
|
After Width: | Height: | Size: 9.3 KiB |
Before Width: | Height: | Size: 9.7 KiB After Width: | Height: | Size: 6.2 KiB |
After Width: | Height: | Size: 9.3 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 6.9 KiB |