[Bf-blender-cvs] [31d480174a8] soc-2020-io-performance: Add support for exporting nurbs curves & surfaces
Ankit Meel
noreply at git.blender.org
Thu Jun 25 14:25:51 CEST 2020
Commit: 31d480174a8caebeeacac14902b02aa5df505a8d
Author: Ankit Meel
Date: Wed Jun 24 15:38:42 2020 +0530
Branches: soc-2020-io-performance
https://developer.blender.org/rB31d480174a8caebeeacac14902b02aa5df505a8d
Add support for exporting nurbs curves & surfaces
Added functionality in OBJNurbs & OBJWriter to export nurbs curve, not
as vertices and edges, but rather control points.
Nurbs surfaces are always converted to mesh and then exported as a
regular mesh with vertices, normals, UV (if it has any), and edges
(if it has no polygons) etc.
===================================================================
M source/blender/io/wavefront_obj/intern/wavefront_obj.hh
M source/blender/io/wavefront_obj/intern/wavefront_obj_exporter.cc
M source/blender/io/wavefront_obj/intern/wavefront_obj_file_handler.cc
M source/blender/io/wavefront_obj/intern/wavefront_obj_file_handler.hh
===================================================================
diff --git a/source/blender/io/wavefront_obj/intern/wavefront_obj.hh b/source/blender/io/wavefront_obj/intern/wavefront_obj.hh
index e9e67712452..799653e435c 100644
--- a/source/blender/io/wavefront_obj/intern/wavefront_obj.hh
+++ b/source/blender/io/wavefront_obj/intern/wavefront_obj.hh
@@ -22,8 +22,8 @@
#define __WAVEFRONT_OBJ_HH__
#include "BKE_context.h"
-#include "BKE_lib_id.h"
#include "BKE_curve.h"
+#include "BKE_lib_id.h"
#include "BKE_mesh.h"
#include "BKE_object.h"
@@ -161,13 +161,26 @@ class OBJMesh {
class OBJNurbs {
public:
- bContext *C;
- const OBJExportParams *export_params;
+ OBJNurbs(bContext *C, Object *export_object) : _C(C), _export_object_eval(export_object)
+ {
+ init_nurbs_curve(export_object);
+ }
+ void get_curve_name(const char **r_object_name);
+ /** Getter for export curve. Used to obtain a curve's nurbs in OBJWriter class. */
+ const Curve *export_curve()
+ {
+ return _export_curve;
+ }
+ /** Get coordinates of a vertex at given point index. */
+ void calc_point_coords(float r_coords[3], uint point_index, Nurb *nurb);
+ /** Get nurbs' degree and number of "curv" points of a nurb. */
+ void get_curve_info(int *r_nurbs_degree, int *r_curv_num, Nurb *nurb);
- Object *object;
- Curve *curve;
- void calc_vertex_coords(float coord[3], uint point_index);
- const char *get_curve_info(int *nurbs_degree, int *curv_num);
+ private:
+ bContext *_C;
+ Object *_export_object_eval;
+ Curve *_export_curve;
+ void init_nurbs_curve(Object *export_object);
};
} // namespace obj
diff --git a/source/blender/io/wavefront_obj/intern/wavefront_obj_exporter.cc b/source/blender/io/wavefront_obj/intern/wavefront_obj_exporter.cc
index b72eaafe59d..401890a9d1d 100644
--- a/source/blender/io/wavefront_obj/intern/wavefront_obj_exporter.cc
+++ b/source/blender/io/wavefront_obj/intern/wavefront_obj_exporter.cc
@@ -77,19 +77,25 @@ void OBJMesh::init_export_mesh(Object *export_object)
}
_tot_vertices = _export_mesh_eval->totvert;
_tot_poly_normals = _export_mesh_eval->totpoly;
- store_world_axes_transform();
}
-
- /* Curves need a new mesh when exported in the form of vertices and edges.
+ /* Curves and nurbs surfaces need a new mesh when exported in the form of vertices and edges.
* For primitive circle, new mesh is redundant, but it behaves more like curves, so kept it here.
*/
- else if (_export_object_eval->type == OB_CURVE && !_export_params->export_curves_as_nurbs) {
+ else {
_export_mesh_eval = BKE_mesh_new_from_object(depsgraph, _export_object_eval, true);
_me_eval_needs_free = true;
- _tot_vertices = _export_mesh_eval->totvert;
- _tot_edges = _export_mesh_eval->totedge;
- store_world_axes_transform();
+ if (_export_object_eval->type == OB_CURVE || _export_mesh_eval->totpoly == 0) {
+ /* Don't export polygon normals when there are no polygons. */
+ _tot_poly_normals = 0;
+ _tot_vertices = _export_mesh_eval->totvert;
+ _tot_edges = _export_mesh_eval->totedge;
+ }
+ else if (_export_object_eval->type == OB_SURF) {
+ _tot_vertices = _export_mesh_eval->totvert;
+ _tot_poly_normals = _export_mesh_eval->totpoly;
+ }
}
+ store_world_axes_transform();
}
/**
@@ -117,6 +123,15 @@ void OBJMesh::triangulate_mesh(Mesh *me_eval)
_export_mesh_eval = BKE_mesh_from_bmesh_for_eval_nomain(bmesh, NULL, me_eval);
BM_mesh_free(bmesh);
}
+/**
+ * Initialise nurbs curve object.
+ */
+void OBJNurbs::init_nurbs_curve(Object *export_object)
+{
+ Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(_C);
+ _export_object_eval = DEG_get_evaluated_object(depsgraph, export_object);
+ _export_curve = (Curve *)_export_object_eval->data;
+}
/**
* Store the product of export axes settings and an object's world transform matrix in
@@ -257,24 +272,29 @@ void OBJMesh::calc_edge_vert_indices(uint r_vert_indices[2], uint edge_index)
}
}
- void OBJNurbs::calc_vertex_coords(float coords[3], uint vert_index)
- {
- Nurb *nu = (Nurb *)curve->nurb.first;
- BPoint *bpoint = nu->bp;
- bpoint += vert_index;
- copy_v3_v3(coords, bpoint->vec);
- }
-
- const char *OBJNurbs::get_curve_info(int *nurbs_degree, int *curv_num)
- {
- Nurb *nurb = (Nurb *)curve->nurb.first;
- *nurbs_degree = nurb->orderu - 1;
- *curv_num = nurb->pntsv * nurb->pntsu;
- if (nurb->flagu & CU_NURB_CYCLIC) {
- *curv_num += *nurbs_degree;
- }
- return object->id.name + 2;
+void OBJNurbs::get_curve_name(const char **r_object_name)
+{
+ *r_object_name = _export_object_eval->id.name + 2;
+}
+
+ /** Get coordinates of a vertex at given point index. */
+void OBJNurbs::calc_point_coords(float r_coords[3], uint vert_index, Nurb *nurb)
+{
+ BPoint *bpoint = nurb->bp;
+ bpoint += vert_index;
+ copy_v3_v3(r_coords, bpoint->vec);
+}
+
+ /** Get nurbs' degree and number of "curv" points of a nurb. */
+void OBJNurbs::get_curve_info(int *r_nurbs_degree, int *r_curv_num, Nurb *nurb)
+{
+ *r_nurbs_degree = nurb->orderu - 1;
+ /* "curv_num" are number of control points in a nurbs. If it is cyclic, degree also adds up. */
+ *r_curv_num = nurb->pntsv * nurb->pntsu;
+ if (nurb->flagu & CU_NURB_CYCLIC) {
+ *r_curv_num += *r_nurbs_degree;
}
+}
/**
* Traverses over and exports a single frame to a single OBJ file.
@@ -288,19 +308,28 @@ static void export_frame(bContext *C, const OBJExportParams *export_params, cons
LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
Object *object_in_layer = base->object;
switch (object_in_layer->type) {
- case OB_MESH:
+ case OB_SURF:
+ case OB_MESH: {
exportable_meshes.append(OBJMesh(C, export_params, object_in_layer));
break;
- case OB_CURVE:
- if (export_params->export_curves_as_nurbs) {
- export_nurbs.append(OBJNurbs());
- export_nurbs.last().object = object_in_layer;
- export_nurbs.last().export_params = export_params;
- export_nurbs.last().C = C;
+ }
+ case OB_CURVE: {
+ Curve *curve = (Curve *)object_in_layer->data;
+ Nurb *nurb = (Nurb *)curve->nurb.first;
+ if (nurb->type == CU_NURBS) {
+ if (export_params->export_curves_as_nurbs) {
+ exportable_nurbs.append(OBJNurbs(C, object_in_layer));
+ }
+ else {
+ exportable_meshes.append(OBJMesh(C, export_params, object_in_layer));
+ }
}
- else {
- exportable_meshes.append(OBJMesh(C, export_params, object_in_layer));
+ if (nurb->type == CU_BEZIER) {
+ exportable_meshes.append(OBJMesh(C, export_params, object_in_layer));
}
+ /* Other types of curves are not supported. */
+ break;
+ }
default:
break;
}
@@ -336,12 +365,11 @@ static void export_frame(bContext *C, const OBJExportParams *export_params, cons
mesh_to_export.destruct();
}
- for (uint ob_iter = 0; ob_iter < export_nurbs.size(); ob_iter++) {
- OBJNurbs &nurbs_to_export = export_nurbs[ob_iter];
- nurbs_to_export.curve = (Curve *)nurbs_to_export.object->data;
- frame_writer.write_nurbs_info(nurbs_to_export);
+ /* Export nurbs in parm form, not as vertices and edges. */
+ for (uint ob_iter = 0; ob_iter < exportable_nurbs.size(); ob_iter++) {
+ OBJNurbs &nurbs_to_export = exportable_nurbs[ob_iter];
+ frame_writer.write_nurbs_curve(nurbs_to_export);
}
- frame_writer.close_file();
}
/**
diff --git a/source/blender/io/wavefront_obj/intern/wavefront_obj_file_handler.cc b/source/blender/io/wavefront_obj/intern/wavefront_obj_file_handler.cc
index 6388d978e3a..c9788876a81 100644
--- a/source/blender/io/wavefront_obj/intern/wavefront_obj_file_handler.cc
+++ b/source/blender/io/wavefront_obj/intern/wavefront_obj_file_handler.cc
@@ -212,46 +212,48 @@ void OBJWriter::write_curve_edges(OBJMesh &obj_mesh_data)
}
}
-void OBJWriter::write_nurbs_info(OBJNurbs &ob_nurbs)
+void OBJWriter::write_nurbs_curve(OBJNurbs &obj_nurbs_data)
{
- // todo object name max is 64.
- Nurb *nurb = (Nurb *)ob_nurbs.curve->nurb.first;
- uint tot_points = nurb->pntsv * nurb->pntsu;
- float point_coord[3];
- for (uint point_idx = 0; point_idx < tot_points; point_idx++) {
- ob_nurbs.calc_vertex_coords(point_coord, point_idx);
- fprintf(outfile, "v %f %f %f\n", point_coord[0], point_coord[1], point_coord[2]);
- }
+ Nurb *nurb = (Nurb *)obj_nurbs_data.export_curve()->nurb.first;
+ for (; nurb; nurb = nurb->next) {
+ /* Total control points in a nurbs. */
+ uint tot_points = nurb->pntsv * nurb->pntsu;
+ float point_coord[3];
+ for (uint point_idx = 0; point_idx < tot_points; point_idx++) {
+ obj_nurbs_data.calc_point_coords(point_coord, point_idx, nurb);
+ fprintf(_outfile, "v %f %f %f\n", point_coord[0], point_coord[1], point_coord[2]);
+ }
- const char *nurbs_name;
- int nurbs_degree;
- /** Number of vertices in the curve + degree of the curve if it is cyclic. */
- int curv_num;
- nurbs_name = ob_nurbs.get_curve_info(&nurbs_degree, &curv_num);
+ const char *nurbs_name;
+ obj_nurbs_data.get_curve_name(&nurbs_name);
+ int nurbs_degree;
+ /** Number of vertices in the curve + degree of the curve if it is cyclic. */
+ int curv_num;
+ obj_nurbs_data.get_curve_info(&nurbs_degree, &curv_num, nurb);
- fprintf(outfile, "g %s\ncstype bspline\n deg %d\n", nurbs_name, nurbs_degree);
+ fprintf(_outfile, "g %s\ncstype bspline\ndeg %d\n", nurbs_name, nurbs_degree);
+ /**
+ * curv_num refers to the vertices above written in relative indices.
+ * 0.0 1.0 -1 -2 -3 -4 for a non-cyclic curve with 4 points.
+ * 0.0 1.0 -1 -2 -3 -4 -1 -2 -3 for a cyclic curve with 4 points.
+ */
+ fprintf(_outfile, "curv 0.0 1.0 ");
+ for (int i = 0; i < curv_num; i++) {
+ fprintf(_outfile, "%d ", -1 * ((i % tot_points) + 1));
+ }
+ fprintf(_outfile, "\n");
- /**
- * curv_num refers to the vertices above written in relative indices.
- * 0.0 1.0 -1 -2 -3 -4 for a non-cyclic curve with 4 points.
- * 0.0 1.0 -1 -2 -3 -4 -1 -2 -3 for a cyclic curve with 4 points.
- */
- fprintf(outfile, "curv 0.0 1.0 ");
- for (int i = 0;
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list