21#include <glibmm/i18n.h>
127 g_warning(
"%s", e.what());
140 if (value && strcmp(value,
"0 : 0 : 0 : 0")) {
147 if (value && strcmp(value,
"0 : 0 : 0 : 0")) {
166 auto oldPersp = cast<Persp3D>(old_ref);
168 oldPersp->remove_box(box);
171 auto persp = cast<Persp3D>(
ref);
172 if ( persp && (
ref != box) )
179 if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) {
195 if ((flags & SP_OBJECT_WRITE_BUILD) && !
repr) {
201 if (flags & SP_OBJECT_WRITE_EXT) {
212 Glib::ustring href =
"#";
246 auto side = cast<Box3DSide>(&obj);
248 side->position_set();
258 gdouble
const sw = hypot(ret[0], ret[1]);
259 gdouble
const sh = hypot(ret[2], ret[3]);
262 auto childitem = cast<SPItem>(&
child);
265 childitem->adjust_stroke(sqrt(fabs(sw * sh)));
268 childitem->adjust_pattern(xform);
271 childitem->adjust_gradient(xform);
343 double z_coord = start_pt[
Proj::Z];
346 double x_coord = start_pt[
Proj::X];
347 double y_coord = start_pt[
Proj::Y];
348 Proj::Pt3 A_proj (x_coord, y_coord, z_coord, 1.0);
349 Proj::Pt3 B_proj (x_coord + diff_x, y_coord, z_coord, 1.0);
350 Proj::Pt3 C_proj (x_coord + diff_x, y_coord + diff_y, z_coord, 1.0);
351 Proj::Pt3 D_proj (x_coord, y_coord + diff_y, z_coord, 1.0);
352 Proj::Pt3 E_proj (x_coord - diff_x, y_coord + diff_y, z_coord, 1.0);
355 Geom::Point A = persp_impl->tmat.image(A_proj).affine();
356 Geom::Point B = persp_impl->tmat.image(B_proj).affine();
357 Geom::Point C = persp_impl->tmat.image(C_proj).affine();
358 Geom::Point D = persp_impl->tmat.image(D_proj).affine();
359 Geom::Point E = persp_impl->tmat.image(E_proj).affine();
360 Geom::Point pt = persp_impl->tmat.image(pt_proj).affine();
369 int num_snap_lines = (
id != -1) ? 3 : 4;
376 snap_pts[3] = diag2.closest_to (pt);
379 gdouble
const zoom = SP_ACTIVE_DESKTOP->current_zoom();
383 for (
int i = 0; i < num_snap_lines; ++i) {
384 snap_dists[i] =
Geom::L2 (snap_pts[i] - pt) * zoom;
389 bool within_tolerance =
true;
390 for (
int i = 0; i < num_snap_lines; ++i) {
392 within_tolerance =
false;
400 for (
int i = 0; i < num_snap_lines; ++i) {
401 if (snap_dists[i] < snap_dist) {
403 snap_dist = snap_dists[i];
410 if (within_tolerance) {
414 result = snap_pts[snap_index];
439 Proj::Pt3 pt_proj (persp_impl->tmat.preimage (new_pos, (
id < 4) ? this->orig_corner0[
Proj::Z] :
462 Proj::Pt3 pt_proj (persp_impl->tmat.preimage (new_pos_snapped,
499 pt_proj =
box3d_snap (
this, -1, pt_proj, old_pos_proj);
540 g_return_if_fail (persp);
572 corner1 = persp_impl->tmat.image(c1).affine();
573 corner2 = persp_impl->tmat.image(c2).affine();
574 corner3 = persp_impl->tmat.image(c3).affine();
575 corner4 = persp_impl->tmat.image(c4).affine();
583 double d0 =
dot(n0,A);
586 double d1 =
dot(
n1,C);
608 if ((
dot(C,n0) < d0) == (
dot(
D,n0) < d0)) {
627 g_return_val_if_fail(persp,
false);
641 auto doc = SP_ACTIVE_DOCUMENT;
643 if (doc->is_yaxisdown()) {
673 switch(central_axis) {
703 g_assert_not_reached();
724 switch(central_axis) {
735 }
else if (inside2 < 0) {
752 }
else if (inside1) {
775 g_assert_not_reached();
793 switch(central_axis) {
796 if (insidezy == -1) {
798 }
else if (insidexy == 1) {
804 if (insideyz == -1) {
838 }
else if (insidexy == -1) {
855 g_assert_not_reached();
886 for (
int i = 0; i < 6; ++i) {
897 if ((pos1 != -1) && (pos2 != -1)){
898 int tmp = z_orders[pos1];
899 z_orders[pos1] = z_orders[pos2];
900 z_orders[pos2] = tmp;
921 for (
int i = 0; i < 3; ++i) {
941 switch (num_finite) {
999 switch (central_axis) {
1035 g_assert_not_reached();
1050 for (
int i = 0; i < 6; ++i) {
1051 if (this->z_orders[i] !=
z_orders[i]) {
1052 for (
int j = i; j < 6; ++j) {
1063 std::map<int, Box3DSide *> sides;
1065 auto side = cast<Box3DSide>(&obj);
1081 std::map<int, Box3DSide *>::iterator side;
1082 for (
int z_order : this->
z_orders) {
1083 side = sides.find(z_order);
1084 if (side != sides.end()) {
1184 for (
int i = 0; i < 3; ++i) {
1203 auto box = cast<SPBox3D>(obj);
1205 boxes.push_back(box);
1206 }
else if (is<SPGroup>(obj)) {
1215 std::list<SPBox3D *> boxes;
1230 if (recompute_corners) {
1245 Glib::ustring href =
"#";
1246 href += new_persp->
getId();
1264 gchar
const *clip_path = this->
getAttribute(
"clip-path");
1270 auto side = cast<Box3DSide>(&obj);
1275 g_warning(
"Non-side item encountered as child of a 3D box.");
1292 g_assert(group !=
nullptr);
1302 return g_strdup(
"");
1314 if (!prefs->
getBool(
"/tools/shapes/3dbox/convertguides",
true)) {
1319 std::list<std::pair<Geom::Point, Geom::Point> > pts;
Lookup dictionary for attributes/properties.
@ INKSCAPE_BOX3D_PERSPECTIVE_ID
TODO: insert short description here.
bool lie_on_same_side(Geom::Point const &A, Geom::Point const &B)
Geom::Point closest_to(Geom::Point const &pt)
3x3 matrix representing an affine transformation.
Affine inverse() const
Compute the inverse matrix.
Infinite line on a plane.
Point pointAt(Coord t) const
Two-dimensional point that doubles as a vector.
void normalize()
Normalize the vector representing the point.
Preference storage class.
bool getBool(Glib::ustring const &pref_path, bool def=false)
Retrieve a Boolean value.
static Preferences * get()
Access the singleton Preferences object.
URI const * getURI() const
Returns a pointer to a URI containing the currently attached URI, or NULL if no URI is currently atta...
void detach()
Detaches from the currently attached URI target, if any; the current referrent is signaled as NULL.
sigc::signal< void(SPObject *, SPObject *)> changedSignal()
Accessor for the referrent change notification signal; this signal is emitted whenever the URIReferen...
void attach(URI const &uri)
Attaches to a URI, relative to the specified document.
Represents an URI as per RFC 2396.
std::string str(char const *baseuri=nullptr) const
Return the string representation of this URI.
Interface for refcounted XML nodes.
virtual void setPosition(int pos)=0
Set the position of this node in parent's child order.
virtual void appendChild(Node *child)=0
Append a node as the last child of this node.
void setAttributeOrRemoveIfEmpty(Inkscape::Util::const_char_ptr key, Inkscape::Util::const_char_ptr value)
Change an attribute of this node.
void setAttribute(Util::const_char_ptr key, Util::const_char_ptr value)
Change an attribute of this node.
virtual Document * document()=0
Get the node's associated document.
Persp3D * getObject() const
void add_box(SPBox3D *box)
static Persp3D * document_first_persp(SPDocument *document)
Geom::Point get_PL_dir_from_pt(Geom::Point const &pt, Proj::Axis axis) const
std::unique_ptr< Persp3DImpl > perspective_impl
Proj::Pt2 get_VP(Proj::Axis axis) const
static bool VP_is_finite(Persp3DImpl *persp_impl, Proj::Axis axis)
void remove_box(SPBox3D *box)
void update(SPCtx *ctx, unsigned int flags) override
virtual const char * display_name()
void set_corner(unsigned int id, Geom::Point const &new_pos, Box3D::Axis movement, bool constrained)
char * description() const override
static SPBox3D * createBox3D(SPItem *parent)
Create a SPBox3D and append it to the parent.
Geom::Point get_center_screen()
void check_for_swapped_coords()
int VP_lies_in_PL_sector(Proj::Axis vpdir, int id1, int id2, Box3D::Axis axis) const
bool recompute_z_orders()
static std::list< SPBox3D * > extract_boxes(SPObject *obj)
Geom::Affine set_transform(Geom::Affine const &transform) override
Persp3DReference * persp_ref
int pt_lies_in_PL_sector(Geom::Point const &pt, int id1, int id2, Box3D::Axis axis) const
Persp3D * get_perspective() const
void corners_for_PLs(Proj::Axis axis, Geom::Point &corner1, Geom::Point &corner2, Geom::Point &corner3, Geom::Point &corner4) const
Geom::Point get_corner_screen(unsigned int id, bool item_coords=true) const
Inkscape::XML::Node * write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags) override
void set_center(Geom::Point const &new_pos, Geom::Point const &old_pos, Box3D::Axis movement, bool constrained)
void convert_to_guides() const override
SPGroup * convert_to_group()
void build(SPDocument *document, Inkscape::XML::Node *repr) override
void set(SPAttr key, char const *value) override
void switch_perspectives(Persp3D *old_persp, Persp3D *new_persp, bool recompute_corners=false)
Proj::Pt3 get_proj_center()
const char * displayName() const override
The item's type name as a translated human string.
Typed SVG document implementation.
void setCurrentPersp3D(Persp3D *const persp)
Inkscape::XML::Document * getReprDoc()
Our Inkscape::XML::Document.
SPObject * getObjectByRepr(Inkscape::XML::Node *repr) const
Persp3D * getCurrentPersp3D()
Inkscape::XML::Node * write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags) override
void set(SPAttr key, char const *value) override
void build(SPDocument *document, Inkscape::XML::Node *repr) override
void update(SPCtx *ctx, unsigned int flags) override
Base class for visual SVG elements.
Geom::Affine i2dt_affine() const
Returns the transformation from item to desktop coords.
SPObject is an abstract base class of all of the document nodes at the SVG document level.
Inkscape::XML::Node * repr
void appendChild(Inkscape::XML::Node *child)
void setAttribute(Inkscape::Util::const_char_ptr key, Inkscape::Util::const_char_ptr value)
char const * getId() const
Returns the objects current ID string.
SPStyle * style
Represents the style properties, whether from presentation attributes, the style attribute,...
void readAttr(char const *key)
Read value of key attribute from XML node into object.
void deleteObject(bool propagate, bool propagate_descendants)
Deletes an object, unparenting it from its parent.
char const * getAttribute(char const *name) const
Editable view implementation.
static char const *const parent
constexpr Coord infinity()
Get a value representing infinity.
Proj::Axis toProj(Box3D::Axis axis)
std::pair< Box3D::Axis, Box3D::FrontOrRear > int_to_face(unsigned id)
int face_to_int(unsigned int face_id)
std::pair< Axis, Axis > get_remaining_axes(Axis axis)
bool lies_in_sector(Geom::Point const &v1, Geom::Point const &v2, Geom::Point const &w)
Angle distance(Angle const &a, Angle const &b)
std::optional< Crossing > OptCrossing
OptCrossing intersection(Ray const &r1, Line const &l2)
Affine identity()
Create an identity matrix.
SBasis L2(D2< SBasis > const &a, unsigned k)
Box3D::Axis toAffine(Proj::Axis axis)
static cairo_user_data_key_t key
static std::map< int, Box3DSide * > box3d_get_sides(SPBox3D *box)
static double remember_snap_threshold
static guint remember_snap_index
static const int MAX_POINT_COUNT
static void box3d_swap_coords(SPBox3D *box, Proj::Axis axis, bool smaller=true)
static void box3d_push_back_corner_pair(SPBox3D const *box, std::list< std::pair< Geom::Point, Geom::Point > > &pts, int c1, int c2)
static void box3d_check_for_swapped_coords(SPBox3D *box, Proj::Axis axis, bool smaller)
static Proj::Pt3 box3d_snap(SPBox3D *box, int id, Proj::Pt3 const &pt_proj, Proj::Pt3 const &start_pt)
static void box3d_aux_set_z_orders(int z_orders[6], int a, int b, int c, int d, int e, int f)
static void box3d_set_new_z_orders_case0(SPBox3D *box, int z_orders[6], Box3D::Axis central_axis)
static void box3d_ref_changed(SPObject *old_ref, SPObject *ref, SPBox3D *box)
Gets called when (re)attached to another perspective.
static Box3D::Axis box3d_everted_directions(SPBox3D *box)
static void box3d_exchange_coords(SPBox3D *box)
static void box3d_set_new_z_orders_case2(SPBox3D *box, int z_orders[6], Box3D::Axis central_axis, Box3D::Axis)
static Proj::Pt3 box3d_get_proj_corner(guint id, Proj::Pt3 const &c0, Proj::Pt3 const &c7)
static void box3d_extract_boxes_rec(SPObject *obj, std::list< SPBox3D * > &boxes)
static void box3d_swap_sides(int z_orders[6], Box3D::Axis axis)
static bool box3d_XY_axes_are_swapped(SPBox3D *box)
static bool box3d_half_line_crosses_joining_line(Geom::Point const &A, Geom::Point const &B, Geom::Point const &C, Geom::Point const &D)
static void box3d_set_new_z_orders_case1(SPBox3D *box, int z_orders[6], Box3D::Axis central_axis, Box3D::Axis fin_axis)
void sp_guide_pt_pairs_to_guides(SPDocument *doc, std::list< std::pair< Geom::Point, Geom::Point > > &pts)
Interface for XML documents.
virtual Node * createElement(char const *name)=0
void dot(Cairo::RefPtr< Cairo::Context > &cr, double x, double y)
Interface for XML documents.