[Bf-blender-cvs] [e395543] hair_system: Define hair root points when copying from particles, by converting the old num/fuv data.
Lukas Tönne
noreply at git.blender.org
Wed Jul 30 10:43:32 CEST 2014
Commit: e395543bf7524a9344c33197dca051f6a682200f
Author: Lukas Tönne
Date: Wed Jul 30 10:42:12 2014 +0200
Branches: hair_system
https://developer.blender.org/rBe395543bf7524a9344c33197dca051f6a682200f
Define hair root points when copying from particles, by converting
the old num/fuv data.
===================================================================
M source/blender/blenkernel/BKE_mesh_sample.h
M source/blender/blenkernel/BKE_particle.h
M source/blender/blenkernel/intern/hair.c
M source/blender/blenkernel/intern/mesh_sample.c
M source/blender/blenkernel/intern/particle.c
M source/blender/editors/physics/hair_ops.c
M source/blender/editors/space_view3d/drawhair.c
M source/blender/makesdna/DNA_hair_types.h
===================================================================
diff --git a/source/blender/blenkernel/BKE_mesh_sample.h b/source/blender/blenkernel/BKE_mesh_sample.h
index 6a0a892..9706bfc 100644
--- a/source/blender/blenkernel/BKE_mesh_sample.h
+++ b/source/blender/blenkernel/BKE_mesh_sample.h
@@ -76,5 +76,6 @@ void BKE_mesh_sample_info_random(struct MSurfaceSampleInfo *info, struct Derived
void BKE_mesh_sample_info_release(struct MSurfaceSampleInfo *info);
void BKE_mesh_sample_surface_array(const struct MSurfaceSampleInfo *info, struct MSurfaceSample *samples, int totsample);
+void BKE_mesh_sample_surface_array_stride(const struct MSurfaceSampleInfo *info, struct MSurfaceSample *first, int stride, int totsample);
#endif /* __BKE_MESH_SAMPLE_H__ */
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index f84a637..f05ccec 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -395,6 +395,7 @@ void psys_interpolate_face(struct MVert *mvert, struct MFace *mface, struct MTFa
float orco[3], float ornor[3]);
float psys_particle_value_from_verts(struct DerivedMesh *dm, short from, struct ParticleData *pa, float *values);
void psys_get_from_key(struct ParticleKey *key, float loc[3], float vel[3], float rot[4], float *time);
+int psys_get_index_on_dm(struct ParticleSystem *psys, struct DerivedMesh *dm, ParticleData *pa, int *mapindex, float mapfw[4]);
/* BLI_bvhtree_ray_cast callback */
void BKE_psys_collision_neartest_cb(void *userdata, int index, const struct BVHTreeRay *ray, struct BVHTreeRayHit *hit);
diff --git a/source/blender/blenkernel/intern/hair.c b/source/blender/blenkernel/intern/hair.c
index ad9d9cc..e621bad 100644
--- a/source/blender/blenkernel/intern/hair.c
+++ b/source/blender/blenkernel/intern/hair.c
@@ -38,6 +38,7 @@
#include "DNA_hair_types.h"
#include "BKE_hair.h"
+#include "BKE_mesh_sample.h"
HairSystem *BKE_hairsys_new(void)
{
@@ -64,6 +65,7 @@ HairSystem *BKE_hairsys_copy(HairSystem *hsys)
{
int totcurves = hsys->totcurves, i;
HairSystem *thsys = MEM_dupallocN(hsys);
+
thsys->curves = MEM_dupallocN(hsys->curves);
for (i = 0; i < totcurves; ++i)
thsys->curves[i].points = MEM_dupallocN(hsys->curves[i].points);
@@ -103,7 +105,7 @@ void BKE_hair_curve_remove(HairSystem *hsys, HairCurve *hair)
memcpy(ncurves, hsys->curves, sizeof(HairCurve) * pos);
}
if (pos < hsys->totcurves - 1) {
- memcpy(ncurves + pos, hsys->curves + (pos + 1), hsys->totcurves - (pos + 1));
+ memcpy(ncurves + pos, hsys->curves + (pos + 1), sizeof(HairCurve) * (hsys->totcurves - (pos + 1)));
}
MEM_freeN(hair->points);
diff --git a/source/blender/blenkernel/intern/mesh_sample.c b/source/blender/blenkernel/intern/mesh_sample.c
index 46e3e99..a1c3e71 100644
--- a/source/blender/blenkernel/intern/mesh_sample.c
+++ b/source/blender/blenkernel/intern/mesh_sample.c
@@ -157,13 +157,18 @@ static void mesh_sample_surface_random(const MSurfaceSampleInfo *info, MSurfaceS
void BKE_mesh_sample_surface_array(const MSurfaceSampleInfo *info, MSurfaceSample *samples, int totsample)
{
+ BKE_mesh_sample_surface_array_stride(info, samples, (int)sizeof(MSurfaceSample), totsample);
+}
+
+void BKE_mesh_sample_surface_array_stride(const struct MSurfaceSampleInfo *info, struct MSurfaceSample *first, int stride, int totsample)
+{
MSurfaceSample *sample;
int i;
switch (info->algorithm) {
case MSS_RANDOM: {
DM_ensure_tessface(info->dm);
- for (sample = samples, i = 0; i < totsample; ++sample, ++i)
+ for (sample = first, i = 0; i < totsample; sample = (MSurfaceSample *)((char *)sample + stride), ++i)
mesh_sample_surface_random(info, sample);
break;
}
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 27d346f..ecefec5 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -1779,6 +1779,11 @@ static int psys_map_index_on_dm(DerivedMesh *dm, int from, int index, int index_
return 1;
}
+int psys_get_index_on_dm(struct ParticleSystem *psys, struct DerivedMesh *dm, ParticleData *pa, int *mapindex, float mapfw[4])
+{
+ return psys_map_index_on_dm(dm, psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, mapindex, mapfw);
+}
+
/* interprets particle data to get a point on a mesh in object space */
void psys_particle_on_dm(DerivedMesh *dm, int from, int index, int index_dmcache,
const float fw[4], float foffset, float vec[3], float nor[3], float utan[3], float vtan[3],
diff --git a/source/blender/editors/physics/hair_ops.c b/source/blender/editors/physics/hair_ops.c
index ac1b4f2..19103c5 100644
--- a/source/blender/editors/physics/hair_ops.c
+++ b/source/blender/editors/physics/hair_ops.c
@@ -37,11 +37,13 @@
#include "BLI_utildefines.h"
#include "DNA_hair_types.h"
+#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_particle_types.h"
#include "BKE_context.h"
+#include "BKE_DerivedMesh.h"
#include "BKE_hair.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
@@ -122,7 +124,59 @@ void HAIR_OT_reset_to_rest_location(wmOperatorType *ot)
/************************ copy hair data from old particles *********************/
-static void hair_copy_from_particles_psys(Object *ob, HairSystem *hsys, ParticleSystem *psys)
+static bool hair_copy_particle_emitter_location(Object *UNUSED(ob), ParticleSystem *psys, ParticleData *pa, struct DerivedMesh *dm, MSurfaceSample *result)
+{
+ float mapfw[4];
+ int mapindex;
+ MVert *mverts = dm->getVertArray(dm);
+ MFace *mface;
+ float *co1, *co2, *co3, *co4;
+ float vec[3];
+ float w[3];
+
+ if (!psys_get_index_on_dm(psys, dm, pa, &mapindex, mapfw))
+ return false;
+
+ mface = dm->getTessFaceData(dm, mapindex, CD_MFACE);
+ mverts = dm->getVertDataArray(dm, CD_MVERT);
+
+ co1 = mverts[mface->v1].co;
+ co2 = mverts[mface->v2].co;
+ co3 = mverts[mface->v3].co;
+
+ if (mface->v4) {
+ co4 = mverts[mface->v4].co;
+
+ interp_v3_v3v3v3v3(vec, co1, co2, co3, co4, mapfw);
+ }
+ else {
+ interp_v3_v3v3v3(vec, co1, co2, co3, mapfw);
+ }
+
+ /* test both triangles of the face */
+ interp_weights_face_v3(w, co1, co2, co3, NULL, vec);
+ if (w[0] <= 1.0f && w[1] <= 1.0f && w[2] <= 1.0f) {
+ result->orig_verts[0] = mface->v1;
+ result->orig_verts[1] = mface->v2;
+ result->orig_verts[2] = mface->v3;
+
+ copy_v3_v3(result->orig_weights, w);
+ return true;
+ }
+ else if (mface->v4) {
+ interp_weights_face_v3(w, co3, co4, co1, NULL, vec);
+ result->orig_verts[0] = mface->v3;
+ result->orig_verts[1] = mface->v4;
+ result->orig_verts[2] = mface->v1;
+
+ copy_v3_v3(result->orig_weights, w);
+ return true;
+ }
+ else
+ return false;
+}
+
+static void hair_copy_from_particles_psys(Object *ob, HairSystem *hsys, ParticleSystem *psys, struct DerivedMesh *dm)
{
HairCurve *hairs;
int tothairs;
@@ -132,30 +186,40 @@ static void hair_copy_from_particles_psys(Object *ob, HairSystem *hsys, Particle
/* matrix for bringing hairs from pob to ob space */
invert_m4_m4(mat, ob->obmat);
+ /* particle emitter mesh data */
+ DM_ensure_tessface(dm);
+
tothairs = psys->totpart;
hairs = BKE_hair_curve_add_multi(hsys, tothairs);
for (i = 0; i < tothairs; ++i) {
ParticleCacheKey *pa_cache = psys->pathcache[i];
+ ParticleData *root = &psys->particles[i];
HairCurve *hair = hairs + i;
HairPoint *points;
int totpoints;
+ if (pa_cache->steps == 0)
+ continue;
+
totpoints = pa_cache->steps + 1;
points = BKE_hair_point_append_multi(hsys, hair, totpoints);
+ hair_copy_particle_emitter_location(ob, psys, root, dm, &hair->root);
+
for (k = 0; k < totpoints; ++k) {
ParticleCacheKey *pa_key = pa_cache + k;
HairPoint *point = points + k;
mul_v3_m4v3(point->rest_co, mat, pa_key->co);
+ /* apply rest position */
copy_v3_v3(point->co, point->rest_co);
zero_v3(point->vel);
}
}
}
-static int hair_copy_from_particles_exec(bContext *C, wmOperator *UNUSED(op))
+static int hair_copy_from_particles_exec(bContext *C, wmOperator *op)
{
Object *ob;
ParticleSystem *psys;
@@ -163,10 +227,20 @@ static int hair_copy_from_particles_exec(bContext *C, wmOperator *UNUSED(op))
ED_hair_get(C, &ob, &hsys);
for (psys = ob->particlesystem.first; psys; psys = psys->next) {
- if (psys->part->type != PART_HAIR)
+ ParticleSystemModifierData *psmd;
+ if (psys->part->type != PART_HAIR) {
+ BKE_reportf(op->reports, RPT_WARNING, "Skipping particle system %s: Not a hair particle system", psys->name);
+ continue;
+ }
+ if (psys->part->from != PART_FROM_FACE) {
+ BKE_reportf(op->reports, RPT_WARNING, "Skipping particle system %s: Must use face emitter mode", psys->name);
continue;
+ }
+
+ psmd = psys_get_modifier(ob, psys);
+ BLI_assert(psmd != NULL);
- hair_copy_from_particles_psys(ob, hsys, psys);
+ hair_copy_from_particles_psys(ob, hsys, psys, psmd->dm);
}
WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
diff --git a/source/blender/editors/space_view3d/drawhair.c b/source/blender/editors/space_view3d/drawhair.c
index a96ede3..f0e9aa8 100644
--- a/source/blender/editors/space_view3d/drawhair.c
+++ b/source/blender/editors/space_view3d/drawhair.c
@@ -41,6 +41,7 @@
#include "BKE_global.h"
#include "BKE_hair.h"
+#include "BKE_mesh_sample.h"
#include "BKE_modifier.h"
#include "view3d_intern.h"
@@ -69,6 +70,7 @@ static void draw_hair_curve(HairSystem *hsys, HairCurve *hair)
}
glEnd();
+#if 0
/* frames */
{
struct HAIR_FrameIterator *iter;
@@ -121,6 +123,7 @@ static void draw_hair_curve(HairSystem *hsys, HairCurve *hair)
HAIR_frame_iter_free(iter);
glEnd();
}
+#endif
#if 0
/* smoothed curve */
@@ -164,6 +167,7 @@ bool draw_hair_system(Scene *UNUSED(scene), View3D *UNUSED(v3d), ARegion *ar, Ba
{
RegionView3D *rv3d = ar->regiondata;
Object *ob = base->object;
+ struct DerivedMesh *dm = ob->derivedFinal;
HairCurve *hair;
int i;
bool retval = true;
@@ -171,6 +175,22 @@ bool draw_hair_system(Scene *UNUSED(scene), View3D *UNUSED(v3d), ARegion *ar, Ba
glLoadMatrixf(rv3d->viewmat);
glMultMatrixf(ob->
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list