diff options
Diffstat (limited to 'src/CGALEvaluator.cc')
-rw-r--r-- | src/CGALEvaluator.cc | 113 |
1 files changed, 62 insertions, 51 deletions
diff --git a/src/CGALEvaluator.cc b/src/CGALEvaluator.cc index 4deb3b3..7c483cb 100644 --- a/src/CGALEvaluator.cc +++ b/src/CGALEvaluator.cc @@ -179,6 +179,64 @@ CGAL_Nef_polyhedron CGALEvaluator::applyHull(const CgaladvNode &node) return N; } +CGAL_Nef_polyhedron CGALEvaluator::applyResize(const CgaladvNode &node) +{ + // Based on resize() in Giles Bathgate's RapCAD (but not exactly) + CGAL_Nef_polyhedron N; + N = applyToChildren(node, CGE_UNION); + + if ( N.isNull() || N.isEmpty() ) return N; + + for (int i=0;i<3;i++) { + if (node.newsize[i]<0) { + PRINT("WARNING: Cannot resize to sizes less than 0."); + return N; + } + } + + CGAL_Iso_cuboid_3 bb; + + if ( N.dim == 2 ) { + CGAL_Iso_rectangle_2e bbox = bounding_box( *N.p2 ); + CGAL_Point_2e min2(bbox.min()), max2(bbox.max()); + CGAL_Point_3 min3(min2.x(),min2.y(),0), max3(max2.x(),max2.y(),0); + bb = CGAL_Iso_cuboid_3( min3, max3 ); + } + else { + bb = bounding_box( *N.p3 ); + } + + Eigen::Matrix<NT,3,1> scale, bbox_size; + scale << 1,1,1; + bbox_size << bb.xmax()-bb.xmin(), bb.ymax()-bb.ymin(), bb.zmax()-bb.zmin(); + for (int i=0;i<3;i++) { + if (node.newsize[i]) { + if (bbox_size[i]==NT(0)) { + PRINT("WARNING: Cannot resize in direction normal to flat object"); + return N; + } + else { + scale[i] = NT(node.newsize[i]) / bbox_size[i]; + } + } + } + NT autoscale = scale.maxCoeff(); + for (int i=0;i<3;i++) { + if (node.autosize[i]) scale[i] = autoscale; + } + + Eigen::Matrix4d t; + t << CGAL::to_double(scale[0]), 0, 0, 0, + 0, CGAL::to_double(scale[1]), 0, 0, + 0, 0, CGAL::to_double(scale[2]), 0, + 0, 0, 0, 1; + + N.transform( Transform3d( t ) ); + return N; +} + + + /* Typical visitor behavior: o In prefix: Check if we're cached -> prune @@ -253,57 +311,7 @@ Response CGALEvaluator::visit(State &state, const TransformNode &node) PRINT("Warning: Transformation matrix contains Not-a-Number and/or Infinity - removing object."); N.reset(); } - - // Then apply transform - // If there is no geometry under the transform, N will be empty - // just silently ignore such nodes - if (!N.isNull()) { - if (N.dim == 2) { - // Unfortunately CGAL provides no transform method for CGAL_Nef_polyhedron2 - // objects. So we convert in to our internal 2d data format, transform it, - // tesselate it and create a new CGAL_Nef_polyhedron2 from it.. What a hack! - - Eigen::Matrix2f testmat; - testmat << node.matrix(0,0), node.matrix(0,1), node.matrix(1,0), node.matrix(1,1); - if (testmat.determinant() == 0) { - PRINT("Warning: Scaling a 2D object with 0 - removing object"); - N.reset(); - } - else { - CGAL_Aff_transformation2 t( - node.matrix(0,0), node.matrix(0,1), node.matrix(0,3), - node.matrix(1,0), node.matrix(1,1), node.matrix(1,3), node.matrix(3,3)); - - DxfData *dd = N.convertToDxfData(); - for (size_t i=0; i < dd->points.size(); i++) { - CGAL_Kernel2::Point_2 p = CGAL_Kernel2::Point_2(dd->points[i][0], dd->points[i][1]); - p = t.transform(p); - dd->points[i][0] = to_double(p.x()); - dd->points[i][1] = to_double(p.y()); - } - - PolySet ps; - ps.is2d = true; - dxf_tesselate(&ps, *dd, 0, true, false, 0); - - N = evaluateCGALMesh(ps); - delete dd; - } - } - else if (N.dim == 3) { - if (node.matrix.matrix().determinant() == 0) { - PRINT("Warning: Scaling a 3D object with 0 - removing object"); - N.reset(); - } - else { - CGAL_Aff_transformation t( - node.matrix(0,0), node.matrix(0,1), node.matrix(0,2), node.matrix(0,3), - node.matrix(1,0), node.matrix(1,1), node.matrix(1,2), node.matrix(1,3), - node.matrix(2,0), node.matrix(2,1), node.matrix(2,2), node.matrix(2,3), node.matrix(3,3)); - N.p3->transform(t); - } - } - } + N.transform( node.matrix ); } else { N = CGALCache::instance()->get(this->tree.getIdString(node)); @@ -358,6 +366,9 @@ Response CGALEvaluator::visit(State &state, const CgaladvNode &node) case HULL: N = applyHull(node); break; + case RESIZE: + N = applyResize(node); + break; } } else { |