goffice r2158 - in trunk: . goffice/graph



Author: jbrefort
Date: Sat Jul 26 06:57:09 2008
New Revision: 2158
URL: http://svn.gnome.org/viewvc/goffice?rev=2158&view=rev

Log:
2008-07-26  Mariusz Adamski  <mariusz adamski gmail com>

	* goffice/graph/gog-chart.c: (xy_grid_3d_can_add),
	(yz_grid_3d_can_add), (zx_grid_3d_can_add), (grid_3d_post_add),
	(xy_grid_3d_post_add), (yz_grid_3d_post_add),
	(zx_grid_3d_post_add), (axis_can_add): implement 3d backplanes.
	* goffice/graph/gog-grid.c: (gog_grid_get_gtype),
	(gog_grid_set_gtype), (gog_grid_set_property),
	(gog_grid_get_property), (gog_grid_class_init), (gog_grid_init),
	(gog_grid_view_xyz_render), (gog_grid_view_render): ditto.
	* goffice/graph/gog-grid.h: ditto.



Modified:
   trunk/ChangeLog
   trunk/NEWS
   trunk/goffice/graph/gog-chart.c
   trunk/goffice/graph/gog-grid.c
   trunk/goffice/graph/gog-grid.h

Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS	(original)
+++ trunk/NEWS	Sat Jul 26 06:57:09 2008
@@ -7,6 +7,10 @@
 Jody:
 	* Reverse legend ordering for stacked 1.5d plots.
 
+Mariusz Adamski:
+	* Added support for 3d plot axes and backplanes.
+	* Implemented a user interface for 3d projection settings.
+
 Morten:
 	* Work around valgrind bug.
 

Modified: trunk/goffice/graph/gog-chart.c
==============================================================================
--- trunk/goffice/graph/gog-chart.c	(original)
+++ trunk/goffice/graph/gog-chart.c	Sat Jul 26 06:57:09 2008
@@ -305,10 +305,45 @@
 }
 
 static gboolean
+xy_grid_3d_can_add (GogObject const *parent)
+{
+	return (GOG_CHART (parent)->axis_set == GOG_AXIS_SET_XYZ &&
+		NULL == gog_object_get_child_by_name (parent, "XY-Backplane"));
+}
+
+static gboolean
+yz_grid_3d_can_add (GogObject const *parent)
+{
+	return (GOG_CHART (parent)->axis_set == GOG_AXIS_SET_XYZ &&
+		NULL == gog_object_get_child_by_name (parent, "YZ-Backplane"));
+}
+
+static gboolean
+zx_grid_3d_can_add (GogObject const *parent)
+{
+	return (GOG_CHART (parent)->axis_set == GOG_AXIS_SET_XYZ &&
+		NULL == gog_object_get_child_by_name (parent, "ZX-Backplane"));
+}
+
+static void
+grid_3d_post_add (GogObject *child, GogGridType t)
+{
+	g_object_set (G_OBJECT (child), "type", (int)t, NULL);
+}
+
+static void xy_grid_3d_post_add    (GogObject *parent, GogObject *child)
+{ grid_3d_post_add (child, GOG_GRID_XY); }
+static void yz_grid_3d_post_add    (GogObject *parent, GogObject *child)
+{ grid_3d_post_add (child, GOG_GRID_YZ); }
+static void zx_grid_3d_post_add    (GogObject *parent, GogObject *child)
+{ grid_3d_post_add (child, GOG_GRID_ZX); }
+
+static gboolean
 axis_can_add (GogObject const *parent, GogAxisType t)
 {
 	GogChart *chart = GOG_CHART (parent);
-	if (chart->axis_set == GOG_AXIS_SET_UNKNOWN)
+	if (chart->axis_set == GOG_AXIS_SET_UNKNOWN
+	    || chart->axis_set == GOG_AXIS_SET_XYZ)
 		return FALSE;
 	return (chart->axis_set & (1 << t)) != 0;
 }
@@ -360,6 +395,18 @@
 	{ N_("Backplane"), "GogGrid",	0,
 	  GOG_POSITION_SPECIAL, GOG_POSITION_SPECIAL, GOG_OBJECT_NAME_BY_ROLE,
 	  role_grid_can_add, NULL, NULL, role_grid_post_add, role_grid_pre_remove, NULL, { -1 } },
+	{ N_("XY-Backplane"), "GogGrid",	0,
+	  GOG_POSITION_SPECIAL, GOG_POSITION_SPECIAL, GOG_OBJECT_NAME_BY_ROLE,
+	  xy_grid_3d_can_add, NULL, NULL, xy_grid_3d_post_add, NULL, NULL,
+	  { GOG_GRID_XY } },
+	{ N_("YZ-Backplane"), "GogGrid",	0,
+	  GOG_POSITION_SPECIAL, GOG_POSITION_SPECIAL, GOG_OBJECT_NAME_BY_ROLE,
+	  yz_grid_3d_can_add, NULL, NULL, yz_grid_3d_post_add, NULL, NULL,
+	  { GOG_GRID_YZ } },
+	{ N_("ZX-Backplane"), "GogGrid",	0,
+	  GOG_POSITION_SPECIAL, GOG_POSITION_SPECIAL, GOG_OBJECT_NAME_BY_ROLE,
+	  zx_grid_3d_can_add, NULL, NULL, zx_grid_3d_post_add, NULL, NULL,
+	  { GOG_GRID_ZX } },
 	{ N_("X-Axis"), "GogAxis",	1,
 	  GOG_POSITION_PADDING, GOG_POSITION_PADDING, GOG_OBJECT_NAME_BY_ROLE,
 	  x_axis_can_add, axis_can_remove, NULL, x_axis_post_add, axis_pre_remove, NULL,

Modified: trunk/goffice/graph/gog-grid.c
==============================================================================
--- trunk/goffice/graph/gog-grid.c	(original)
+++ trunk/goffice/graph/gog-grid.c	Sat Jul 26 06:57:09 2008
@@ -23,6 +23,7 @@
 #include <goffice/graph/gog-grid.h>
 #include <goffice/graph/gog-chart.h>
 #include <goffice/graph/gog-chart-map.h>
+#include <goffice/graph/gog-chart-map-3d.h>
 #include <goffice/graph/gog-styled-object.h>
 #include <goffice/graph/gog-style.h>
 #include <goffice/graph/gog-view.h>
@@ -35,15 +36,25 @@
 
 #include <gsf/gsf-impl-utils.h>
 
+#ifdef GOFFICE_WITH_GTK
+#include <gtk/gtkcombobox.h>
+#endif
+
 struct _GogGrid {
 	GogStyledObject	base;
+	GogGridType type;
 };
 typedef GogStyledObjectClass GogGridClass;
 
-
 static GType gog_grid_view_get_type (void);
+static GObjectClass *parent_klass;
 static GogViewClass *gview_parent_klass;
 
+enum {
+	GRID_PROP_0,
+	GRID_PROP_TYPE,
+};
+
 static void
 gog_grid_init_style (GogStyledObject *gso, GogStyle *style)
 {
@@ -52,18 +63,73 @@
 		style, GOG_OBJECT (gso), 0, FALSE);
 }
 
+GogGridType
+gog_grid_get_gtype (GogGrid const *grid)
+{
+	g_return_val_if_fail (IS_GOG_GRID (grid), GOG_GRID_UNKNOWN);
+	return grid->type;
+}
+
+void
+gog_grid_set_gtype (GogGrid *grid, GogGridType type)
+{
+	g_return_if_fail (IS_GOG_GRID (grid));
+	grid->type = type;
+}
+
+static void
+gog_grid_set_property (GObject *obj, guint param_id,
+		       GValue const *value, GParamSpec *pspec)
+{
+	GogGrid *grid = GOG_GRID (obj);
+
+	if (param_id == GRID_PROP_TYPE)
+		grid->type = g_value_get_int (value);
+	else
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec);
+}
+
+static void
+gog_grid_get_property (GObject *obj, guint param_id,
+		       GValue *value, GParamSpec *pspec)
+{
+	GogGrid const *grid = GOG_GRID (obj);
+
+	if (param_id == GRID_PROP_TYPE)
+		g_value_set_int (value, grid->type);
+	else
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec);
+}
+
 static void
-gog_grid_class_init (GogGridClass *klass)
+gog_grid_class_init (GObjectClass *gobject_klass)
 {
-	GogObjectClass *gog_klass = (GogObjectClass *) klass;
-	GogStyledObjectClass *style_klass = (GogStyledObjectClass *) klass;
+	GogObjectClass *gog_klass = (GogObjectClass *) gobject_klass;
+	GogStyledObjectClass *style_klass = (GogStyledObjectClass *) gog_klass;
+
+	parent_klass = g_type_class_peek_parent (gobject_klass);
+	gobject_klass->set_property = gog_grid_set_property;
+	gobject_klass->get_property = gog_grid_get_property;
+
+	g_object_class_install_property (gobject_klass, GRID_PROP_TYPE,
+		g_param_spec_int ("type", _("Type"),
+			_("Numerical type of this backplane"),
+			GOG_GRID_UNKNOWN, GOG_GRID_TYPES, GOG_GRID_UNKNOWN, 
+			GSF_PARAM_STATIC | G_PARAM_READWRITE
+			| GOG_PARAM_PERSISTENT));
 
 	gog_klass->view_type	= gog_grid_view_get_type ();
 	style_klass->init_style = gog_grid_init_style;
 }
 
+static void
+gog_grid_init (GogGrid *grid)
+{
+	grid->type = GOG_GRID_UNKNOWN;
+}
+
 GSF_CLASS (GogGrid, gog_grid,
-	   gog_grid_class_init, NULL,
+	   gog_grid_class_init, gog_grid_init,
 	   GOG_STYLED_OBJECT_TYPE)
 
 /************************************************************************/
@@ -75,6 +141,106 @@
 #define GOG_GRID_VIEW(o)	(G_TYPE_CHECK_INSTANCE_CAST ((o), GOG_GRID_VIEW_TYPE, GogGridView))
 #define IS_GOG_GRID_VIEW(o)	(G_TYPE_CHECK_INSTANCE_TYPE ((o), GOG_GRID_VIEW_TYPE))
 
+
+static void
+gog_grid_view_xyz_render (GogGrid *grid, GogView *view,
+			  GogChart *chart, GogViewAllocation const *plot_area)
+{
+	GogAxisMap *a_map = NULL;
+	GOPath *path;
+	unsigned int i;
+	GogAxis *xaxis, *yaxis, *zaxis;
+	GSList *axes;
+	GogChartMap3D *c_map;
+	double ax, ay, az, bx, by, bz;
+	double *px[] = {&ax, &ax, &bx, &bx, &ax, &ax, &bx, &bx};
+	double *py[] = {&ay, &by, &by, &ay, &ay, &by, &by, &ay};
+	double *pz[] = {&az, &az, &az, &az, &bz, &bz, &bz, &bz};
+	double rx[8], ry[8], rz[8];
+
+	/* Note: Anti-clockwise order in each face,
+	 * important for calculating normals */
+	const int faces[] = {
+		3, 2, 1, 0, /* Bottom */
+		4, 5, 6, 7, /* Top */
+		0, 1, 5, 4, /* Left */
+		2, 3, 7, 6, /* Right */
+		1, 2, 6, 5, /* Front */
+		0, 4, 7, 3  /* Back */
+	};
+	int bp_faces[] = {0, 0};
+	int fv[] = {0, 0, 0, 0, 0, 0};
+
+	axes  = gog_chart_get_axes (chart, GOG_AXIS_X);
+	xaxis = GOG_AXIS (axes->data);
+	axes  = gog_chart_get_axes (chart, GOG_AXIS_Y);
+	yaxis = GOG_AXIS (axes->data);
+	axes  = gog_chart_get_axes (chart, GOG_AXIS_Z);
+	zaxis = GOG_AXIS (axes->data);
+	c_map = gog_chart_map_3d_new (chart, plot_area,
+		xaxis, yaxis, zaxis);
+
+	a_map = gog_chart_map_3d_get_axis_map (c_map, 0);
+	gog_axis_map_get_bounds (a_map, &ax, &bx);
+	a_map = gog_chart_map_3d_get_axis_map (c_map, 1);
+	gog_axis_map_get_bounds (a_map, &ay, &by);
+	a_map = gog_chart_map_3d_get_axis_map (c_map, 2);
+	gog_axis_map_get_bounds (a_map, &az, &bz);
+
+	/* Projecting vertices */
+	for (i = 0; i < 8; ++i)
+		gog_chart_map_3d_to_view (c_map, *px[i], *py[i], *pz[i],
+		                          &rx[i], &ry[i], &rz[i]);
+	gog_chart_map_3d_free (c_map);
+
+	/* Determining visibility of each face */
+	for (i = 0; i < 24; i += 4) {
+		int A = faces[i];
+		int B = faces[i + 1];
+		int C = faces[i + 3];
+		double tmp = (rx[B] - rx[A]) * (ry[C] - ry[A])
+		           - (ry[B] - ry[A]) * (rx[C] - rx[A]);
+		if (tmp < 0)
+			fv[i / 4] = 1;
+	}
+
+	switch (grid->type) {
+	case GOG_GRID_XY:
+		bp_faces[0] = 0;
+		bp_faces[1] = 4;
+		break;
+	case GOG_GRID_YZ:
+		bp_faces[0] = 8;
+		bp_faces[1] = 12;
+		break;
+	case GOG_GRID_ZX:
+		bp_faces[0] = 16;
+		bp_faces[1] = 20;
+		break;
+	default:
+		return;
+	}
+
+	path = go_path_new ();
+	go_path_set_options (path, GO_PATH_OPTIONS_SHARP);
+	for (i = 0; i < 2; ++i) {
+		int face = bp_faces[i];
+		if (fv[face / 4] == 0)
+			continue;
+		go_path_move_to (path, rx[faces[face]],
+		                 ry[faces[face]]);
+		go_path_line_to (path, rx[faces[face + 1]],
+		                 ry[faces[face + 1]]);
+		go_path_line_to (path, rx[faces[face + 2]],
+		                 ry[faces[face + 2]]);
+		go_path_line_to (path, rx[faces[face + 3]],
+		                 ry[faces[face + 3]]);
+		go_path_close (path);
+	}
+	gog_renderer_draw_shape (view->renderer, path);
+	go_path_free (path);
+}
+
 static void
 gog_grid_view_render (GogView *view, GogViewAllocation const *bbox)
 {
@@ -151,6 +317,9 @@
 			break;
 					 }
 		case GOG_AXIS_SET_XYZ:
+			gog_grid_view_xyz_render (grid, view, chart,
+			                          &view->allocation);
+			break;
 		case GOG_AXIS_SET_XY_pseudo_3d:
 		case GOG_AXIS_SET_FUNDAMENTAL:
 		case GOG_AXIS_SET_ALL:

Modified: trunk/goffice/graph/gog-grid.h
==============================================================================
--- trunk/goffice/graph/gog-grid.h	(original)
+++ trunk/goffice/graph/gog-grid.h	Sat Jul 26 06:57:09 2008
@@ -26,12 +26,23 @@
 
 G_BEGIN_DECLS
 
+typedef enum {
+	GOG_GRID_UNKNOWN = -1,
+	GOG_GRID_XY,
+	GOG_GRID_YZ,
+	GOG_GRID_ZX,
+	GOG_GRID_TYPES
+} GogGridType;
+
 #define GOG_GRID_TYPE	(gog_grid_get_type ())
 #define GOG_GRID(o)	(G_TYPE_CHECK_INSTANCE_CAST ((o), GOG_GRID_TYPE, GogGrid))
 #define IS_GOG_GRID(o)	(G_TYPE_CHECK_INSTANCE_TYPE ((o), GOG_GRID_TYPE))
 
 GType gog_grid_get_type (void);
 
+GogGridType	gog_grid_get_gtype (GogGrid const *grid);
+void		gog_grid_set_gtype (GogGrid *grid, GogGridType type);
+
 G_END_DECLS
 
 #endif /* GOG_GRID_H */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]