From 9c0a6a79d3a382b03b8a33b90a1f0ef548747390 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Mon, 6 Jan 2014 18:29:10 +0100 Subject: [PATCH] Incomplete work for porting BoundingBox to XS --- lib/Slic3r/Geometry/BoundingBox.pm | 8 -- lib/Slic3r/Model.pm | 4 +- lib/Slic3r/TriangleMesh.pm | 5 -- xs/MANIFEST | 5 ++ xs/src/BoundingBox.cpp | 111 ++++++++++++++++++++++++++++ xs/src/BoundingBox.hpp | 71 ++++++++++++++++++ xs/src/Layer.hpp | 13 ++++ xs/src/Model.hpp | 115 +++++++++++++++++++++++++++++ xs/src/Point.hpp | 20 ++++- xs/src/TriangleMesh.cpp | 11 +++ xs/src/TriangleMesh.hpp | 2 + xs/src/myinit.h | 1 + xs/t/17_boundingbox.t | 20 +++++ xs/xsp/BoundingBox.xsp | 43 +++++++++++ xs/xsp/TriangleMesh.xsp | 6 ++ xs/xsp/my.map | 2 + xs/xsp/typemap.xspt | 2 + 17 files changed, 421 insertions(+), 18 deletions(-) create mode 100644 xs/src/BoundingBox.cpp create mode 100644 xs/src/BoundingBox.hpp create mode 100644 xs/src/Layer.hpp create mode 100644 xs/src/Model.hpp create mode 100644 xs/t/17_boundingbox.t create mode 100644 xs/xsp/BoundingBox.xsp diff --git a/lib/Slic3r/Geometry/BoundingBox.pm b/lib/Slic3r/Geometry/BoundingBox.pm index 0236cd33f..2b8cae358 100644 --- a/lib/Slic3r/Geometry/BoundingBox.pm +++ b/lib/Slic3r/Geometry/BoundingBox.pm @@ -33,14 +33,6 @@ sub new_from_bb { ]); } -# 3D -sub new_from_points_3D { - my $class = shift; - my ($points) = @_; - - return $class->new(extents => [ Slic3r::Geometry::bounding_box_3D($points) ]); -} - sub merge { my $class = shift; my (@bounding_boxes) = @_; diff --git a/lib/Slic3r/Model.pm b/lib/Slic3r/Model.pm index 3cbd97493..129f6fc27 100644 --- a/lib/Slic3r/Model.pm +++ b/lib/Slic3r/Model.pm @@ -88,7 +88,7 @@ sub set_material { my $self = shift; my ($material_id, $attributes) = @_; - return $self->materials->{$material_id} = Slic3r::Model::Region->new( + return $self->materials->{$material_id} = Slic3r::Model::Material->new( model => $self, attributes => $attributes || {}, ); @@ -319,7 +319,7 @@ sub get_material_name { return $name; } -package Slic3r::Model::Region; +package Slic3r::Model::Material; use Moo; has 'model' => (is => 'ro', weak_ref => 1, required => 1); diff --git a/lib/Slic3r/TriangleMesh.pm b/lib/Slic3r/TriangleMesh.pm index 838e1cd32..b59b44a30 100644 --- a/lib/Slic3r/TriangleMesh.pm +++ b/lib/Slic3r/TriangleMesh.pm @@ -24,9 +24,4 @@ sub facets_count { return $self->stats->{number_of_facets}; } -sub bounding_box { - my $self = shift; - return Slic3r::Geometry::BoundingBox->new_from_bb($self->bb3); -} - 1; diff --git a/xs/MANIFEST b/xs/MANIFEST index fc52e2497..23943e92e 100644 --- a/xs/MANIFEST +++ b/xs/MANIFEST @@ -8,6 +8,8 @@ src/admesh/stl.h src/admesh/stl_io.c src/admesh/stlinit.c src/admesh/util.c +src/BoundingBox.cpp +src/BoundingBox.hpp src/clipper.cpp src/clipper.hpp src/ClipperUtils.cpp @@ -26,8 +28,10 @@ src/Flow.cpp src/Flow.hpp src/Geometry.cpp src/Geometry.hpp +src/Layer.hpp src/Line.cpp src/Line.hpp +src/Model.hpp src/MultiPoint.cpp src/MultiPoint.hpp src/myinit.h @@ -68,6 +72,7 @@ t/13_polylinecollection.t t/14_geometry.t t/15_config.t t/16_flow.t +t/17_boundingbox.t xsp/Clipper.xsp xsp/Config.xsp xsp/ExPolygon.xsp diff --git a/xs/src/BoundingBox.cpp b/xs/src/BoundingBox.cpp new file mode 100644 index 000000000..f45050278 --- /dev/null +++ b/xs/src/BoundingBox.cpp @@ -0,0 +1,111 @@ +#include "BoundingBox.hpp" +#include + +namespace Slic3r { + +template +BoundingBoxBase::BoundingBoxBase(const std::vector points) +{ + for (typename std::vector::const_iterator it = points.begin(); it != points.end(); ++it) { + this->min.x = std::min(it->x, this->min.x); + this->min.y = std::min(it->y, this->min.y); + this->max.x = std::max(it->x, this->max.x); + this->max.y = std::max(it->y, this->max.y); + } +} + +template +BoundingBox3Base::BoundingBox3Base(const std::vector points) + : BoundingBoxBase(points) +{ + for (typename std::vector::const_iterator it = points.begin(); it != points.end(); ++it) { + this->min.z = std::min(it->z, this->min.z); + this->max.z = std::max(it->z, this->max.z); + } +} + +void +BoundingBox::polygon(Polygon* polygon) const +{ + polygon->points.clear(); + polygon->points.resize(4); + polygon->points[0].x = this->min.x; + polygon->points[0].y = this->min.y; + polygon->points[1].x = this->max.x; + polygon->points[1].y = this->min.y; + polygon->points[2].x = this->max.x; + polygon->points[2].y = this->max.y; + polygon->points[3].x = this->min.x; + polygon->points[3].y = this->max.y; +} + +template void +BoundingBoxBase::scale(double factor) +{ + this->min.scale(factor); + this->max.scale(factor); +} + +template void +BoundingBoxBase::merge(const BoundingBoxBase &bb) +{ + this->min.x = std::min(bb.min.x, this->min.x); + this->min.y = std::min(bb.min.y, this->min.y); + this->max.x = std::max(bb.max.x, this->max.x); + this->max.y = std::max(bb.max.y, this->max.y); +} + +template void +BoundingBox3Base::merge(const BoundingBox3Base &bb) +{ + BoundingBoxBase::merge(bb); + this->min.z = std::min(bb.min.z, this->min.z); + this->max.z = std::max(bb.max.z, this->max.z); +} + +template PointClass +BoundingBox2Base::size() const +{ + return PointClass(this->max.x - this->min.x, this->max.y - this->min.y); +} + +template PointClass +BoundingBox3Base::size() const +{ + return PointClass(this->max.x - this->min.x, this->max.y - this->min.y, this->max.z - this->min.z); +} + +template void +BoundingBox2Base::translate(coordf_t x, coordf_t y) +{ + this->min.translate(x, y); + this->max.translate(x, y); +} + +template void +BoundingBox3Base::translate(coordf_t x, coordf_t y, coordf_t z) +{ + this->min.translate(x, y, z); + this->max.translate(x, y, z); +} + +template PointClass +BoundingBox2Base::center() const +{ + return PointClass( + (this->max.x - this->min.x)/2, + (this->max.y - this->min.y)/2 + ); +} + +template PointClass +BoundingBox3Base::center() const +{ + return PointClass( + (this->max.x - this->min.x)/2, + (this->max.y - this->min.y)/2, + (this->max.z - this->min.z)/2 + ); +} + +} diff --git a/xs/src/BoundingBox.hpp b/xs/src/BoundingBox.hpp new file mode 100644 index 000000000..6068fa191 --- /dev/null +++ b/xs/src/BoundingBox.hpp @@ -0,0 +1,71 @@ +#ifndef slic3r_BoundingBox_hpp_ +#define slic3r_BoundingBox_hpp_ + +#include +#include "Point.hpp" +#include "Polygon.hpp" + +namespace Slic3r { + +typedef Point Size; +typedef Point3 Size3; +typedef Pointf Sizef; +typedef Pointf3 Sizef3; + +template +class BoundingBoxBase +{ + public: + PointClass min; + PointClass max; + + BoundingBoxBase(const std::vector points); + //virtual ~BoundingBoxBase() {}; + void merge(const BoundingBoxBase &bb); + void scale(double factor); +}; + +template +class BoundingBox2Base : public BoundingBoxBase +{ + public: + BoundingBox2Base(const std::vector points) : BoundingBoxBase(points) {}; + //virtual ~BoundingBox2Base() {}; + PointClass size() const; + void translate(coordf_t x, coordf_t y); + PointClass center() const; +}; + +template +class BoundingBox3Base : public BoundingBoxBase +{ + public: + BoundingBox3Base(const std::vector points); + //virtual ~BoundingBox3Base() {}; + void merge(const BoundingBox3Base &bb); + PointClass size() const; + void translate(coordf_t x, coordf_t y, coordf_t z); + PointClass center() const; +}; + +class BoundingBox : public BoundingBox2Base +{ + public: + void polygon(Polygon* polygon) const; + + BoundingBox(); + BoundingBox(const Points points) : BoundingBox2Base(points) {}; +}; + +class BoundingBoxf : public BoundingBox2Base {}; +class BoundingBox3 : public BoundingBox3Base {}; + +class BoundingBoxf3 : public BoundingBox3Base { + public: + BoundingBoxf3(); + BoundingBoxf3(const std::vector points) : BoundingBox3Base(points) {}; +}; + +} + +#endif diff --git a/xs/src/Layer.hpp b/xs/src/Layer.hpp new file mode 100644 index 000000000..62da84f81 --- /dev/null +++ b/xs/src/Layer.hpp @@ -0,0 +1,13 @@ +#ifndef slic3r_Layer_hpp_ +#define slic3r_Layer_hpp_ + +#include + +namespace Slic3r { + +typedef std::pair t_layer_height_range; +typedef std::map t_layer_height_ranges; + +} + +#endif diff --git a/xs/src/Model.hpp b/xs/src/Model.hpp new file mode 100644 index 000000000..28dcc6008 --- /dev/null +++ b/xs/src/Model.hpp @@ -0,0 +1,115 @@ +#ifndef slic3r_Model_hpp_ +#define slic3r_Model_hpp_ + +#include +#include "Config.hpp" +#include "Layer.hpp" +#include "Point.hpp" +#include "TriangleMesh.hpp" +#include +#include +#include +#include + +namespace Slic3r { + +class ModelInstance; +class ModelMaterial; +class ModelObject; +class ModelVolume; + +typedef std::string t_model_material_id; +typedef std::string t_model_material_attribute; +typedef std::map t_model_material_attributes; + +class Model +{ + public: + std::map materials; + std::vector objects; + + Model(); + ~Model(); + ModelObject* add_object(const ModelObject &object); + void delete_object(size_t obj_idx); + void delete_all_objects(); + void set_material(t_model_material_id material_id, const t_model_material_attributes &attributes); + void duplicate_objects_grid(coordf_t x, coordf_t y, coordf_t distance); + void duplicate_objects(size_t copies_num, coordf_t distance, const BoundingBox &bb); + void arrange_objects(coordf_t distance, const BoundingBox &bb); + void duplicate(size_t copies_num, coordf_t distance, const BoundingBox &bb); + bool has_objects_with_no_instances() const; + void bounding_box(BoundingBox* bb) const; + void align_to_origin(); + void center_instances_around_point(const Pointf &point); + void translate(coordf_t x, coordf_t y, coordf_t z); + void mesh(TriangleMesh* mesh) const; + void split_meshes(); + std::string get_material_name(t_model_material_id material_id); + + private: + void _arrange(const std::vector &sizes, coordf_t distance, const BoundingBox &bb) const; +}; + +class ModelMaterial +{ + public: + Model* model; + t_model_material_attributes attributes; + DynamicConfig config; +}; + +class ModelObject +{ + public: + Model* model; + std::string input_file; + std::vector instances; + std::vector volumes; + DynamicConfig config; + t_layer_height_ranges layer_height_ranges; + + ModelObject(); + ~ModelObject(); + ModelInstance* add_instance(const ModelInstance &instance); + ModelVolume* add_volume(const ModelVolume &volume); + void delete_last_instance(); + void raw_mesh(TriangleMesh* mesh) const; + void mesh(TriangleMesh* mesh) const; + void instance_bounding_box(size_t instance_idx, BoundingBox* bb) const; + void align_to_origin(); + void center_around_origin(); + void translate(coordf_t x, coordf_t y, coordf_t z); + size_t materials_count() const; + void unique_materials(std::vector* materials) const; + size_t facets_count() const; + bool needed_repair() const; + + private: + BoundingBox bb; + void update_bounding_box(); +}; + +class ModelVolume +{ + public: + ModelObject* object; + t_model_material_id material_id; + TriangleMesh mesh; +}; + +class ModelInstance +{ + public: + ModelObject* object; + double rotation; + double scaling_factor; + Pointf offset; + + void transform_mesh(TriangleMesh* mesh, bool dont_translate) const; + void transform_polygon(Polygon* polygon) const; +}; + +} + +#endif diff --git a/xs/src/Point.hpp b/xs/src/Point.hpp index 385f99cdb..0ca93bf66 100644 --- a/xs/src/Point.hpp +++ b/xs/src/Point.hpp @@ -44,12 +44,19 @@ class Point #endif }; +class Point3 : public Point +{ + public: + coord_t z; + explicit Point3(coord_t _x = 0, coord_t _y = 0, coord_t _z = 0): Point(_x, _y), z(_z) {}; +}; + class Pointf { public: - double x; - double y; - explicit Pointf(double _x = 0, double _y = 0): x(_x), y(_y) {}; + coordf_t x; + coordf_t y; + explicit Pointf(coordf_t _x = 0, coordf_t _y = 0): x(_x), y(_y) {}; #ifdef SLIC3RXS void from_SV(SV* point_sv); @@ -57,6 +64,13 @@ class Pointf #endif }; +class Pointf3 : public Pointf +{ + public: + coordf_t z; + explicit Pointf3(coordf_t _x = 0, coordf_t _y = 0, coordf_t _z = 0): Pointf(_x, _y), z(_z) {}; +}; + } #endif diff --git a/xs/src/TriangleMesh.cpp b/xs/src/TriangleMesh.cpp index debd2155c..ff8108b67 100644 --- a/xs/src/TriangleMesh.cpp +++ b/xs/src/TriangleMesh.cpp @@ -615,6 +615,17 @@ TriangleMesh::convex_hull(Polygon* hull) Slic3r::Geometry::convex_hull(pp, hull); } +void +TriangleMesh::bounding_box(BoundingBoxf3* bb) const +{ + bb->min.x = this->stl.stats.min.x; + bb->min.y = this->stl.stats.min.y; + bb->min.z = this->stl.stats.min.z; + bb->max.x = this->stl.stats.max.x; + bb->max.y = this->stl.stats.max.y; + bb->max.z = this->stl.stats.max.z; +} + void TriangleMesh::require_shared_vertices() { diff --git a/xs/src/TriangleMesh.hpp b/xs/src/TriangleMesh.hpp index e4892f8a4..b151dcc6e 100644 --- a/xs/src/TriangleMesh.hpp +++ b/xs/src/TriangleMesh.hpp @@ -4,6 +4,7 @@ #include #include #include +#include "BoundingBox.hpp" #include "Point.hpp" #include "Polygon.hpp" #include "ExPolygon.hpp" @@ -34,6 +35,7 @@ class TriangleMesh void merge(const TriangleMesh* mesh); void horizontal_projection(ExPolygons &retval) const; void convex_hull(Polygon* hull); + void bounding_box(BoundingBoxf3* bb) const; stl_file stl; bool repaired; diff --git a/xs/src/myinit.h b/xs/src/myinit.h index fcbaca5c0..0156f64dc 100644 --- a/xs/src/myinit.h +++ b/xs/src/myinit.h @@ -24,6 +24,7 @@ extern "C" { #define scale_(val) (val / SCALING_FACTOR) #define unscale(val) (val * SCALING_FACTOR) typedef long coord_t; +typedef double coordf_t; namespace Slic3r {} using namespace Slic3r; diff --git a/xs/t/17_boundingbox.t b/xs/t/17_boundingbox.t new file mode 100644 index 000000000..28e74dd00 --- /dev/null +++ b/xs/t/17_boundingbox.t @@ -0,0 +1,20 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use Slic3r::XS; +use Test::More tests => 3; + +{ + my @points = ( + Slic3r::Point->new(100, 200), + Slic3r::Point->new(500, -600), + ); + my $bb = Slic3r::Geometry::BoundingBox->new_from_points(\@points); + isa_ok $flow, 'Slic3r::Geometry::BoundingBox', 'new_from_points'; + is_deeply $bb->min_point->pp, [100,-600], 'min_point'; + is_deeply $bb->max_point->pp, [500,200], 'max_point'; +} + +__END__ diff --git a/xs/xsp/BoundingBox.xsp b/xs/xsp/BoundingBox.xsp new file mode 100644 index 000000000..5e496383d --- /dev/null +++ b/xs/xsp/BoundingBox.xsp @@ -0,0 +1,43 @@ +%module{Slic3r::XS}; + +%{ +#include +#include "BoundingBox.hpp" +#include "Point.hpp" +%} + +%name{Slic3r::Geometry::BoundingBox} class BoundingBox { + ~BoundingBox(); + BoundingBox* clone() + %code{% const char* CLASS = "Slic3r::Geometry::BoundingBox"; RETVAL = new BoundingBox(*THIS); %}; + void merge(BoundingBox* bb) %code{% THIS->merge(*bb); %}; + void scale(double factor); + void translate(double x, double y); + Polygon* polygon() + %code{% const char* CLASS = "Slic3r::Polygon"; RETVAL = new Polygon(); THIS->polygon(RETVAL); %}; + Point* size() + %code{% const char* CLASS = "Slic3r::Point"; RETVAL = new Point(THIS->size()); %}; + Point* center() + %code{% const char* CLASS = "Slic3r::Point"; RETVAL = new Point(THIS->center()); %}; + Point* min_point() + %code{% const char* CLASS = "Slic3r::Point"; RETVAL = new Point(THIS->min); %}; + Point* max_point() + %code{% const char* CLASS = "Slic3r::Point"; RETVAL = new Point(THIS->max); %}; + double x_min() %code{% RETVAL = THIS->min.x; %}; + double x_max() %code{% RETVAL = THIS->max.x; %}; + double y_min() %code{% RETVAL = THIS->min.y; %}; + double y_max() %code{% RETVAL = THIS->max.y; %}; + +%{ + +BoundingBox* +BoundingBox::new_from_points(CLASS, points) + char* CLASS + Points points + CODE: + RETVAL = new BoundingBox(points); + OUTPUT: + RETVAL + +%} +}; diff --git a/xs/xsp/TriangleMesh.xsp b/xs/xsp/TriangleMesh.xsp index 80160926d..c27751891 100644 --- a/xs/xsp/TriangleMesh.xsp +++ b/xs/xsp/TriangleMesh.xsp @@ -26,6 +26,12 @@ void merge(TriangleMesh* mesh); ExPolygons horizontal_projection() %code{% THIS->horizontal_projection(RETVAL); %}; + BoundingBoxf3* bounding_box() + %code{% + const char* CLASS = "Slic3r::Geometry::BoundingBoxf3"; + RETVAL = new BoundingBoxf3(); + THIS->bounding_box(RETVAL); + %}; %{ SV* diff --git a/xs/xsp/my.map b/xs/xsp/my.map index 6a02d9432..c12d341fa 100644 --- a/xs/xsp/my.map +++ b/xs/xsp/my.map @@ -1,6 +1,8 @@ std::vector T_STD_VECTOR_INT t_config_option_key T_STD_STRING +BoundingBox* O_OBJECT +BoundingBoxf3* O_OBJECT DynamicPrintConfig* O_OBJECT PrintObjectConfig* O_OBJECT PrintRegionConfig* O_OBJECT diff --git a/xs/xsp/typemap.xspt b/xs/xsp/typemap.xspt index 46a037526..4e351d43a 100644 --- a/xs/xsp/typemap.xspt +++ b/xs/xsp/typemap.xspt @@ -8,6 +8,8 @@ %typemap{SV*}; %typemap{AV*}; %typemap{Point*}; +%typemap{BoundingBox*}; +%typemap{BoundingBoxf3*}; %typemap{DynamicPrintConfig*}; %typemap{PrintObjectConfig*}; %typemap{PrintRegionConfig*};