Merge branch 'master' into blender2.8
Conflicts: source/blender/editors/screen/screen_edit.c
This commit is contained in:
@@ -80,122 +80,180 @@ inline void face_split_tri_indices(const int face_flag,
|
|||||||
struct MikkUserData {
|
struct MikkUserData {
|
||||||
MikkUserData(const BL::Mesh& b_mesh,
|
MikkUserData(const BL::Mesh& b_mesh,
|
||||||
BL::MeshTextureFaceLayer *layer,
|
BL::MeshTextureFaceLayer *layer,
|
||||||
int num_faces)
|
const Mesh *mesh,
|
||||||
: b_mesh(b_mesh),
|
float3 *tangent,
|
||||||
layer(layer),
|
float *tangent_sign)
|
||||||
num_faces(num_faces)
|
: mesh(mesh),
|
||||||
|
texface(NULL),
|
||||||
|
orco(NULL),
|
||||||
|
tangent(tangent),
|
||||||
|
tangent_sign(tangent_sign)
|
||||||
{
|
{
|
||||||
tangent.resize(num_faces*4);
|
Attribute *attr_vN = mesh->attributes.find(ATTR_STD_VERTEX_NORMAL);
|
||||||
|
vertex_normal = attr_vN->data_float3();
|
||||||
|
|
||||||
|
if(layer == NULL) {
|
||||||
|
Attribute *attr_orco = mesh->attributes.find(ATTR_STD_GENERATED);
|
||||||
|
orco = attr_orco->data_float3();
|
||||||
|
mesh_texture_space(*(BL::Mesh*)&b_mesh, orco_loc, orco_size);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Attribute *attr_uv = mesh->attributes.find(ustring(layer->name()));
|
||||||
|
if(attr_uv != NULL) {
|
||||||
|
texface = attr_uv->data_float3();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BL::Mesh b_mesh;
|
const Mesh *mesh;
|
||||||
BL::MeshTextureFaceLayer *layer;
|
|
||||||
int num_faces;
|
int num_faces;
|
||||||
vector<float4> tangent;
|
|
||||||
|
float3 *vertex_normal;
|
||||||
|
float3 *texface;
|
||||||
|
float3 *orco;
|
||||||
|
float3 orco_loc, orco_size;
|
||||||
|
|
||||||
|
float3 *tangent;
|
||||||
|
float *tangent_sign;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int mikk_get_num_faces(const SMikkTSpaceContext *context)
|
static int mikk_get_num_faces(const SMikkTSpaceContext *context)
|
||||||
{
|
{
|
||||||
MikkUserData *userdata = (MikkUserData*)context->m_pUserData;
|
const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData;
|
||||||
return userdata->num_faces;
|
return userdata->mesh->num_triangles();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mikk_get_num_verts_of_face(const SMikkTSpaceContext *context, const int face_num)
|
static int mikk_get_num_verts_of_face(const SMikkTSpaceContext * /*context*/,
|
||||||
|
const int /*face_num*/)
|
||||||
{
|
{
|
||||||
MikkUserData *userdata = (MikkUserData*)context->m_pUserData;
|
return 3;
|
||||||
BL::MeshTessFace f = userdata->b_mesh.tessfaces[face_num];
|
|
||||||
int4 vi = get_int4(f.vertices_raw());
|
|
||||||
|
|
||||||
return (vi[3] == 0)? 3: 4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mikk_get_position(const SMikkTSpaceContext *context, float P[3], const int face_num, const int vert_num)
|
static void mikk_get_position(const SMikkTSpaceContext *context,
|
||||||
|
float P[3],
|
||||||
|
const int face_num, const int vert_num)
|
||||||
{
|
{
|
||||||
MikkUserData *userdata = (MikkUserData*)context->m_pUserData;
|
const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData;
|
||||||
BL::MeshTessFace f = userdata->b_mesh.tessfaces[face_num];
|
const Mesh *mesh = userdata->mesh;
|
||||||
int4 vi = get_int4(f.vertices_raw());
|
const int vert_index = mesh->triangles[face_num * 3 + vert_num];
|
||||||
BL::MeshVertex v = userdata->b_mesh.vertices[vi[vert_num]];
|
const float3 vP = mesh->verts[vert_index];
|
||||||
float3 vP = get_float3(v.co());
|
|
||||||
|
|
||||||
P[0] = vP.x;
|
P[0] = vP.x;
|
||||||
P[1] = vP.y;
|
P[1] = vP.y;
|
||||||
P[2] = vP.z;
|
P[2] = vP.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mikk_get_texture_coordinate(const SMikkTSpaceContext *context, float uv[2], const int face_num, const int vert_num)
|
static void mikk_get_texture_coordinate(const SMikkTSpaceContext *context,
|
||||||
|
float uv[2],
|
||||||
|
const int face_num, const int vert_num)
|
||||||
{
|
{
|
||||||
MikkUserData *userdata = (MikkUserData*)context->m_pUserData;
|
const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData;
|
||||||
if(userdata->layer != NULL) {
|
if(userdata->texface != NULL) {
|
||||||
BL::MeshTextureFace tf = userdata->layer->data[face_num];
|
const size_t corner_index = face_num * 3 + vert_num;
|
||||||
float3 tfuv;
|
float3 tfuv = userdata->texface[corner_index];
|
||||||
|
|
||||||
switch(vert_num) {
|
|
||||||
case 0:
|
|
||||||
tfuv = get_float3(tf.uv1());
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
tfuv = get_float3(tf.uv2());
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
tfuv = get_float3(tf.uv3());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
tfuv = get_float3(tf.uv4());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
uv[0] = tfuv.x;
|
uv[0] = tfuv.x;
|
||||||
uv[1] = tfuv.y;
|
uv[1] = tfuv.y;
|
||||||
}
|
}
|
||||||
else {
|
else if(userdata->orco != NULL) {
|
||||||
int vert_idx = userdata->b_mesh.tessfaces[face_num].vertices()[vert_num];
|
const Mesh *mesh = userdata->mesh;
|
||||||
float3 orco =
|
const size_t vertex_index = mesh->triangles[face_num * 3 + vert_num];
|
||||||
get_float3(userdata->b_mesh.vertices[vert_idx].undeformed_co());
|
const float3 orco_loc = userdata->orco_loc;
|
||||||
float2 tmp = map_to_sphere(make_float3(orco[0], orco[1], orco[2]));
|
const float3 orco_size = userdata->orco_size;
|
||||||
|
const float3 orco = (userdata->orco[vertex_index] + orco_loc) / orco_size;
|
||||||
|
|
||||||
|
const float2 tmp = map_to_sphere(orco);
|
||||||
uv[0] = tmp.x;
|
uv[0] = tmp.x;
|
||||||
uv[1] = tmp.y;
|
uv[1] = tmp.y;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
uv[0] = 0.0f;
|
||||||
|
uv[1] = 0.0f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mikk_get_normal(const SMikkTSpaceContext *context, float N[3], const int face_num, const int vert_num)
|
static void mikk_get_normal(const SMikkTSpaceContext *context, float N[3],
|
||||||
|
const int face_num, const int vert_num)
|
||||||
{
|
{
|
||||||
MikkUserData *userdata = (MikkUserData*)context->m_pUserData;
|
const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData;
|
||||||
BL::MeshTessFace f = userdata->b_mesh.tessfaces[face_num];
|
const Mesh *mesh = userdata->mesh;
|
||||||
float3 vN;
|
float3 vN;
|
||||||
|
if(mesh->smooth[face_num]) {
|
||||||
if(f.use_smooth()) {
|
const size_t vert_index = mesh->triangles[face_num * 3 + vert_num];
|
||||||
int4 vi = get_int4(f.vertices_raw());
|
vN = userdata->vertex_normal[vert_index];
|
||||||
BL::MeshVertex v = userdata->b_mesh.vertices[vi[vert_num]];
|
|
||||||
vN = get_float3(v.normal());
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
vN = get_float3(f.normal());
|
const Mesh::Triangle tri = mesh->get_triangle(face_num);
|
||||||
|
vN = tri.compute_normal(&mesh->verts[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
N[0] = vN.x;
|
N[0] = vN.x;
|
||||||
N[1] = vN.y;
|
N[1] = vN.y;
|
||||||
N[2] = vN.z;
|
N[2] = vN.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mikk_set_tangent_space(const SMikkTSpaceContext *context, const float T[], const float sign, const int face, const int vert)
|
static void mikk_set_tangent_space(const SMikkTSpaceContext *context,
|
||||||
|
const float T[],
|
||||||
|
const float sign,
|
||||||
|
const int face_num, const int vert_num)
|
||||||
{
|
{
|
||||||
MikkUserData *userdata = (MikkUserData*)context->m_pUserData;
|
MikkUserData *userdata = (MikkUserData *)context->m_pUserData;
|
||||||
|
const size_t corner_index = face_num * 3 + vert_num;
|
||||||
userdata->tangent[face*4 + vert] = make_float4(T[0], T[1], T[2], sign);
|
userdata->tangent[corner_index] = make_float3(T[0], T[1], T[2]);
|
||||||
|
if(userdata->tangent_sign != NULL) {
|
||||||
|
userdata->tangent_sign[corner_index] = sign;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mikk_compute_tangents(BL::Mesh& b_mesh,
|
static void mikk_compute_tangents(const BL::Mesh& b_mesh,
|
||||||
BL::MeshTextureFaceLayer *b_layer,
|
BL::MeshTextureFaceLayer *b_layer,
|
||||||
Mesh *mesh,
|
Mesh *mesh,
|
||||||
const vector<int>& nverts,
|
|
||||||
const vector<int>& face_flags,
|
|
||||||
bool need_sign,
|
bool need_sign,
|
||||||
bool active_render)
|
bool active_render)
|
||||||
{
|
{
|
||||||
/* setup userdata */
|
/* Create tangent attributes. */
|
||||||
MikkUserData userdata(b_mesh, b_layer, nverts.size());
|
Attribute *attr;
|
||||||
|
ustring name;
|
||||||
|
if(b_layer != NULL) {
|
||||||
|
name = ustring((string(b_layer->name().c_str()) + ".tangent").c_str());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
name = ustring("orco.tangent");
|
||||||
|
}
|
||||||
|
if(active_render) {
|
||||||
|
attr = mesh->attributes.add(ATTR_STD_UV_TANGENT, name);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
attr = mesh->attributes.add(name,
|
||||||
|
TypeDesc::TypeVector,
|
||||||
|
ATTR_ELEMENT_CORNER);
|
||||||
|
}
|
||||||
|
float3 *tangent = attr->data_float3();
|
||||||
|
/* Create bitangent sign attribute. */
|
||||||
|
float *tangent_sign = NULL;
|
||||||
|
if(need_sign) {
|
||||||
|
Attribute *attr_sign;
|
||||||
|
ustring name_sign;
|
||||||
|
if(b_layer != NULL) {
|
||||||
|
name_sign = ustring((string(b_layer->name().c_str()) +
|
||||||
|
".tangent_sign").c_str());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
name_sign = ustring("orco.tangent_sign");
|
||||||
|
}
|
||||||
|
|
||||||
/* setup interface */
|
if(active_render) {
|
||||||
|
attr_sign = mesh->attributes.add(ATTR_STD_UV_TANGENT_SIGN,
|
||||||
|
name_sign);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
attr_sign = mesh->attributes.add(name_sign,
|
||||||
|
TypeDesc::TypeFloat,
|
||||||
|
ATTR_ELEMENT_CORNER);
|
||||||
|
}
|
||||||
|
tangent_sign = attr_sign->data_float();
|
||||||
|
}
|
||||||
|
/* Setup userdata. */
|
||||||
|
MikkUserData userdata(b_mesh, b_layer, mesh, tangent, tangent_sign);
|
||||||
|
/* Setup interface. */
|
||||||
SMikkTSpaceInterface sm_interface;
|
SMikkTSpaceInterface sm_interface;
|
||||||
memset(&sm_interface, 0, sizeof(sm_interface));
|
memset(&sm_interface, 0, sizeof(sm_interface));
|
||||||
sm_interface.m_getNumFaces = mikk_get_num_faces;
|
sm_interface.m_getNumFaces = mikk_get_num_faces;
|
||||||
@@ -204,80 +262,13 @@ static void mikk_compute_tangents(BL::Mesh& b_mesh,
|
|||||||
sm_interface.m_getTexCoord = mikk_get_texture_coordinate;
|
sm_interface.m_getTexCoord = mikk_get_texture_coordinate;
|
||||||
sm_interface.m_getNormal = mikk_get_normal;
|
sm_interface.m_getNormal = mikk_get_normal;
|
||||||
sm_interface.m_setTSpaceBasic = mikk_set_tangent_space;
|
sm_interface.m_setTSpaceBasic = mikk_set_tangent_space;
|
||||||
|
/* Setup context. */
|
||||||
/* setup context */
|
|
||||||
SMikkTSpaceContext context;
|
SMikkTSpaceContext context;
|
||||||
memset(&context, 0, sizeof(context));
|
memset(&context, 0, sizeof(context));
|
||||||
context.m_pUserData = &userdata;
|
context.m_pUserData = &userdata;
|
||||||
context.m_pInterface = &sm_interface;
|
context.m_pInterface = &sm_interface;
|
||||||
|
/* Compute tangents. */
|
||||||
/* compute tangents */
|
|
||||||
genTangSpaceDefault(&context);
|
genTangSpaceDefault(&context);
|
||||||
|
|
||||||
/* create tangent attributes */
|
|
||||||
Attribute *attr;
|
|
||||||
ustring name;
|
|
||||||
if(b_layer != NULL)
|
|
||||||
name = ustring((string(b_layer->name().c_str()) + ".tangent").c_str());
|
|
||||||
else
|
|
||||||
name = ustring("orco.tangent");
|
|
||||||
|
|
||||||
if(active_render)
|
|
||||||
attr = mesh->attributes.add(ATTR_STD_UV_TANGENT, name);
|
|
||||||
else
|
|
||||||
attr = mesh->attributes.add(name, TypeDesc::TypeVector, ATTR_ELEMENT_CORNER);
|
|
||||||
|
|
||||||
float3 *tangent = attr->data_float3();
|
|
||||||
|
|
||||||
/* create bitangent sign attribute */
|
|
||||||
float *tangent_sign = NULL;
|
|
||||||
|
|
||||||
if(need_sign) {
|
|
||||||
Attribute *attr_sign;
|
|
||||||
ustring name_sign;
|
|
||||||
if(b_layer != NULL)
|
|
||||||
name_sign = ustring((string(b_layer->name().c_str()) + ".tangent_sign").c_str());
|
|
||||||
else
|
|
||||||
name_sign = ustring("orco.tangent_sign");
|
|
||||||
|
|
||||||
if(active_render)
|
|
||||||
attr_sign = mesh->attributes.add(ATTR_STD_UV_TANGENT_SIGN, name_sign);
|
|
||||||
else
|
|
||||||
attr_sign = mesh->attributes.add(name_sign, TypeDesc::TypeFloat, ATTR_ELEMENT_CORNER);
|
|
||||||
|
|
||||||
tangent_sign = attr_sign->data_float();
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i = 0; i < nverts.size(); i++) {
|
|
||||||
int tri_a[3], tri_b[3];
|
|
||||||
face_split_tri_indices(face_flags[i], tri_a, tri_b);
|
|
||||||
|
|
||||||
tangent[0] = float4_to_float3(userdata.tangent[i*4 + tri_a[0]]);
|
|
||||||
tangent[1] = float4_to_float3(userdata.tangent[i*4 + tri_a[1]]);
|
|
||||||
tangent[2] = float4_to_float3(userdata.tangent[i*4 + tri_a[2]]);
|
|
||||||
tangent += 3;
|
|
||||||
|
|
||||||
if(tangent_sign) {
|
|
||||||
tangent_sign[0] = userdata.tangent[i*4 + tri_a[0]].w;
|
|
||||||
tangent_sign[1] = userdata.tangent[i*4 + tri_a[1]].w;
|
|
||||||
tangent_sign[2] = userdata.tangent[i*4 + tri_a[2]].w;
|
|
||||||
tangent_sign += 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(nverts[i] == 4) {
|
|
||||||
tangent[0] = float4_to_float3(userdata.tangent[i*4 + tri_b[0]]);
|
|
||||||
tangent[1] = float4_to_float3(userdata.tangent[i*4 + tri_b[1]]);
|
|
||||||
tangent[2] = float4_to_float3(userdata.tangent[i*4 + tri_b[2]]);
|
|
||||||
tangent += 3;
|
|
||||||
|
|
||||||
if(tangent_sign) {
|
|
||||||
tangent_sign[0] = userdata.tangent[i*4 + tri_b[0]].w;
|
|
||||||
tangent_sign[1] = userdata.tangent[i*4 + tri_b[1]].w;
|
|
||||||
tangent_sign[2] = userdata.tangent[i*4 + tri_b[2]].w;
|
|
||||||
tangent_sign += 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create Volume Attribute */
|
/* Create Volume Attribute */
|
||||||
@@ -450,21 +441,39 @@ static void attr_create_uv_map(Scene *scene,
|
|||||||
BL::Mesh::tessface_uv_textures_iterator l;
|
BL::Mesh::tessface_uv_textures_iterator l;
|
||||||
|
|
||||||
for(b_mesh.tessface_uv_textures.begin(l); l != b_mesh.tessface_uv_textures.end(); ++l) {
|
for(b_mesh.tessface_uv_textures.begin(l); l != b_mesh.tessface_uv_textures.end(); ++l) {
|
||||||
bool active_render = l->active_render();
|
const bool active_render = l->active_render();
|
||||||
AttributeStandard std = (active_render)? ATTR_STD_UV: ATTR_STD_NONE;
|
AttributeStandard uv_std = (active_render)? ATTR_STD_UV: ATTR_STD_NONE;
|
||||||
ustring name = ustring(l->name().c_str());
|
ustring uv_name = ustring(l->name().c_str());
|
||||||
|
AttributeStandard tangent_std = (active_render)? ATTR_STD_UV_TANGENT
|
||||||
|
: ATTR_STD_NONE;
|
||||||
|
ustring tangent_name = ustring(
|
||||||
|
(string(l->name().c_str()) + ".tangent").c_str());
|
||||||
|
|
||||||
|
/* Denotes whether UV map was requested directly. */
|
||||||
|
const bool need_uv = mesh->need_attribute(scene, uv_name) ||
|
||||||
|
mesh->need_attribute(scene, uv_std);
|
||||||
|
/* Denotes whether tangent was requested directly. */
|
||||||
|
const bool need_tangent =
|
||||||
|
mesh->need_attribute(scene, tangent_name) ||
|
||||||
|
(active_render && mesh->need_attribute(scene, tangent_std));
|
||||||
|
|
||||||
/* UV map */
|
/* UV map */
|
||||||
if(mesh->need_attribute(scene, name) || mesh->need_attribute(scene, std)) {
|
/* NOTE: We create temporary UV layer if its needed for tangent but
|
||||||
Attribute *attr;
|
* wasn't requested by other nodes in shaders.
|
||||||
|
*/
|
||||||
if(active_render)
|
Attribute *uv_attr = NULL;
|
||||||
attr = mesh->attributes.add(std, name);
|
if(need_uv || need_tangent) {
|
||||||
else
|
if(active_render) {
|
||||||
attr = mesh->attributes.add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CORNER);
|
uv_attr = mesh->attributes.add(uv_std, uv_name);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
uv_attr = mesh->attributes.add(uv_name,
|
||||||
|
TypeDesc::TypePoint,
|
||||||
|
ATTR_ELEMENT_CORNER);
|
||||||
|
}
|
||||||
|
|
||||||
BL::MeshTextureFaceLayer::data_iterator t;
|
BL::MeshTextureFaceLayer::data_iterator t;
|
||||||
float3 *fdata = attr->data_float3();
|
float3 *fdata = uv_attr->data_float3();
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
|
|
||||||
for(l->data.begin(t); t != l->data.end(); ++t, ++i) {
|
for(l->data.begin(t); t != l->data.end(); ++t, ++i) {
|
||||||
@@ -494,33 +503,32 @@ static void attr_create_uv_map(Scene *scene,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* UV tangent */
|
/* UV tangent */
|
||||||
std = (active_render)? ATTR_STD_UV_TANGENT: ATTR_STD_NONE;
|
if(need_tangent) {
|
||||||
name = ustring((string(l->name().c_str()) + ".tangent").c_str());
|
AttributeStandard sign_std =
|
||||||
|
(active_render)? ATTR_STD_UV_TANGENT_SIGN
|
||||||
if(mesh->need_attribute(scene, name) || (active_render && mesh->need_attribute(scene, std))) {
|
: ATTR_STD_NONE;
|
||||||
std = (active_render)? ATTR_STD_UV_TANGENT_SIGN: ATTR_STD_NONE;
|
ustring sign_name = ustring(
|
||||||
name = ustring((string(l->name().c_str()) + ".tangent_sign").c_str());
|
(string(l->name().c_str()) + ".tangent_sign").c_str());
|
||||||
bool need_sign = (mesh->need_attribute(scene, name) || mesh->need_attribute(scene, std));
|
bool need_sign = (mesh->need_attribute(scene, sign_name) ||
|
||||||
|
mesh->need_attribute(scene, sign_std));
|
||||||
mikk_compute_tangents(b_mesh,
|
mikk_compute_tangents(b_mesh,
|
||||||
&(*l),
|
&(*l),
|
||||||
mesh,
|
mesh,
|
||||||
nverts,
|
|
||||||
face_flags,
|
|
||||||
need_sign,
|
need_sign,
|
||||||
active_render);
|
active_render);
|
||||||
}
|
}
|
||||||
|
/* Remove temporarily created UV attribute. */
|
||||||
|
if(!need_uv && uv_attr != NULL) {
|
||||||
|
mesh->attributes.remove(uv_attr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(mesh->need_attribute(scene, ATTR_STD_UV_TANGENT)) {
|
else if(mesh->need_attribute(scene, ATTR_STD_UV_TANGENT)) {
|
||||||
bool need_sign = mesh->need_attribute(scene, ATTR_STD_UV_TANGENT_SIGN);
|
bool need_sign = mesh->need_attribute(scene, ATTR_STD_UV_TANGENT_SIGN);
|
||||||
mikk_compute_tangents(b_mesh,
|
mikk_compute_tangents(b_mesh, NULL, mesh, need_sign, true);
|
||||||
NULL,
|
if(!mesh->need_attribute(scene, ATTR_STD_GENERATED)) {
|
||||||
mesh,
|
mesh->attributes.remove(ATTR_STD_GENERATED);
|
||||||
nverts,
|
}
|
||||||
face_flags,
|
|
||||||
need_sign,
|
|
||||||
true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -758,7 +766,13 @@ static void create_mesh(Scene *scene,
|
|||||||
N = attr_N->data_float3();
|
N = attr_N->data_float3();
|
||||||
|
|
||||||
/* create generated coordinates from undeformed coordinates */
|
/* create generated coordinates from undeformed coordinates */
|
||||||
if(mesh->need_attribute(scene, ATTR_STD_GENERATED)) {
|
const bool need_default_tangent =
|
||||||
|
(subdivision == false) &&
|
||||||
|
(b_mesh.tessface_uv_textures.length() == 0) &&
|
||||||
|
(mesh->need_attribute(scene, ATTR_STD_UV_TANGENT));
|
||||||
|
if(mesh->need_attribute(scene, ATTR_STD_GENERATED) ||
|
||||||
|
need_default_tangent)
|
||||||
|
{
|
||||||
Attribute *attr = attributes.add(ATTR_STD_GENERATED);
|
Attribute *attr = attributes.add(ATTR_STD_GENERATED);
|
||||||
attr->flags |= ATTR_SUBDIVIDED;
|
attr->flags |= ATTR_SUBDIVIDED;
|
||||||
|
|
||||||
@@ -768,8 +782,9 @@ static void create_mesh(Scene *scene,
|
|||||||
float3 *generated = attr->data_float3();
|
float3 *generated = attr->data_float3();
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
|
|
||||||
for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v)
|
for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v) {
|
||||||
generated[i++] = get_float3(v->undeformed_co())*size - loc;
|
generated[i++] = get_float3(v->undeformed_co())*size - loc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create faces */
|
/* create faces */
|
||||||
|
|||||||
@@ -502,6 +502,16 @@ Attribute *AttributeSet::find(AttributeRequest& req)
|
|||||||
return find(req.std);
|
return find(req.std);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AttributeSet::remove(Attribute *attribute)
|
||||||
|
{
|
||||||
|
if(attribute->std == ATTR_STD_NONE) {
|
||||||
|
remove(attribute->name);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
remove(attribute->std);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void AttributeSet::resize(bool reserve_only)
|
void AttributeSet::resize(bool reserve_only)
|
||||||
{
|
{
|
||||||
foreach(Attribute& attr, attributes) {
|
foreach(Attribute& attr, attributes) {
|
||||||
|
|||||||
@@ -120,6 +120,8 @@ public:
|
|||||||
|
|
||||||
Attribute *find(AttributeRequest& req);
|
Attribute *find(AttributeRequest& req);
|
||||||
|
|
||||||
|
void remove(Attribute *attribute);
|
||||||
|
|
||||||
void resize(bool reserve_only = false);
|
void resize(bool reserve_only = false);
|
||||||
void clear();
|
void clear();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -107,6 +107,19 @@ void Mesh::Triangle::verts_for_step(const float3 *verts,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float3 Mesh::Triangle::compute_normal(const float3 *verts) const
|
||||||
|
{
|
||||||
|
const float3& v0 = verts[v[0]];
|
||||||
|
const float3& v1 = verts[v[1]];
|
||||||
|
const float3& v2 = verts[v[2]];
|
||||||
|
const float3 norm = cross(v1 - v0, v2 - v0);
|
||||||
|
const float normlen = len(norm);
|
||||||
|
if(normlen == 0.0f) {
|
||||||
|
return make_float3(1.0f, 0.0f, 0.0f);
|
||||||
|
}
|
||||||
|
return norm / normlen;
|
||||||
|
}
|
||||||
|
|
||||||
/* Curve */
|
/* Curve */
|
||||||
|
|
||||||
void Mesh::Curve::bounds_grow(const int k, const float3 *curve_keys, const float *curve_radius, BoundBox& bounds) const
|
void Mesh::Curve::bounds_grow(const int k, const float3 *curve_keys, const float *curve_radius, BoundBox& bounds) const
|
||||||
@@ -701,21 +714,6 @@ void Mesh::compute_bounds()
|
|||||||
bounds = bnds;
|
bounds = bnds;
|
||||||
}
|
}
|
||||||
|
|
||||||
static float3 compute_face_normal(const Mesh::Triangle& t, float3 *verts)
|
|
||||||
{
|
|
||||||
float3 v0 = verts[t.v[0]];
|
|
||||||
float3 v1 = verts[t.v[1]];
|
|
||||||
float3 v2 = verts[t.v[2]];
|
|
||||||
|
|
||||||
float3 norm = cross(v1 - v0, v2 - v0);
|
|
||||||
float normlen = len(norm);
|
|
||||||
|
|
||||||
if(normlen == 0.0f)
|
|
||||||
return make_float3(1.0f, 0.0f, 0.0f);
|
|
||||||
|
|
||||||
return norm / normlen;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Mesh::add_face_normals()
|
void Mesh::add_face_normals()
|
||||||
{
|
{
|
||||||
/* don't compute if already there */
|
/* don't compute if already there */
|
||||||
@@ -733,7 +731,7 @@ void Mesh::add_face_normals()
|
|||||||
float3 *verts_ptr = verts.data();
|
float3 *verts_ptr = verts.data();
|
||||||
|
|
||||||
for(size_t i = 0; i < triangles_size; i++) {
|
for(size_t i = 0; i < triangles_size; i++) {
|
||||||
fN[i] = compute_face_normal(get_triangle(i), verts_ptr);
|
fN[i] = get_triangle(i).compute_normal(verts_ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -795,7 +793,7 @@ void Mesh::add_vertex_normals()
|
|||||||
|
|
||||||
for(size_t i = 0; i < triangles_size; i++) {
|
for(size_t i = 0; i < triangles_size; i++) {
|
||||||
for(size_t j = 0; j < 3; j++) {
|
for(size_t j = 0; j < 3; j++) {
|
||||||
float3 fN = compute_face_normal(get_triangle(i), mP);
|
float3 fN = get_triangle(i).compute_normal(mP);
|
||||||
mN[get_triangle(i).v[j]] += fN;
|
mN[get_triangle(i).v[j]] += fN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,6 +70,8 @@ public:
|
|||||||
size_t num_steps,
|
size_t num_steps,
|
||||||
size_t step,
|
size_t step,
|
||||||
float3 r_verts[3]) const;
|
float3 r_verts[3]) const;
|
||||||
|
|
||||||
|
float3 compute_normal(const float3 *verts) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
Triangle get_triangle(size_t i) const
|
Triangle get_triangle(size_t i) const
|
||||||
|
|||||||
@@ -982,6 +982,8 @@ public:
|
|||||||
|
|
||||||
/* ideally we could beter detect this, but we can't query this now */
|
/* ideally we could beter detect this, but we can't query this now */
|
||||||
bool has_spatial_varying() { return true; }
|
bool has_spatial_varying() { return true; }
|
||||||
|
bool has_volume_support() { return true; }
|
||||||
|
|
||||||
virtual bool equals(const ShaderNode& /*other*/) { return false; }
|
virtual bool equals(const ShaderNode& /*other*/) { return false; }
|
||||||
|
|
||||||
string filepath;
|
string filepath;
|
||||||
|
|||||||
@@ -420,7 +420,7 @@ Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
|
|||||||
ListBase rl, rv;
|
ListBase rl, rv;
|
||||||
|
|
||||||
sce_copy = BKE_scene_add(bmain, sce->id.name + 2);
|
sce_copy = BKE_scene_add(bmain, sce->id.name + 2);
|
||||||
|
|
||||||
rl = sce_copy->r.layers;
|
rl = sce_copy->r.layers;
|
||||||
rv = sce_copy->r.views;
|
rv = sce_copy->r.views;
|
||||||
curvemapping_free_data(&sce_copy->r.mblur_shutter_curve);
|
curvemapping_free_data(&sce_copy->r.mblur_shutter_curve);
|
||||||
@@ -517,6 +517,8 @@ Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
BKE_id_copy_ex(bmain, (ID *)sce, (ID **)&sce_copy, LIB_ID_COPY_ACTIONS, false);
|
BKE_id_copy_ex(bmain, (ID *)sce, (ID **)&sce_copy, LIB_ID_COPY_ACTIONS, false);
|
||||||
|
id_us_min(&sce_copy->id);
|
||||||
|
id_us_ensure_real(&sce_copy->id);
|
||||||
|
|
||||||
/* Extra actions, most notably SCE_FULL_COPY also duplicates several 'children' datablocks... */
|
/* Extra actions, most notably SCE_FULL_COPY also duplicates several 'children' datablocks... */
|
||||||
|
|
||||||
|
|||||||
@@ -444,7 +444,7 @@ void UI_popup_block_close(struct bContext *C, struct wmWindow *win, uiBlock *blo
|
|||||||
* */
|
* */
|
||||||
|
|
||||||
uiBlock *UI_block_begin(const struct bContext *C, struct ARegion *region, const char *name, short dt);
|
uiBlock *UI_block_begin(const struct bContext *C, struct ARegion *region, const char *name, short dt);
|
||||||
void UI_block_end_ex(const struct bContext *C, uiBlock *block, const int xy[2]);
|
void UI_block_end_ex(const struct bContext *C, uiBlock *block, const int xy[2], int r_xy[2]);
|
||||||
void UI_block_end(const struct bContext *C, uiBlock *block);
|
void UI_block_end(const struct bContext *C, uiBlock *block);
|
||||||
void UI_block_draw(const struct bContext *C, struct uiBlock *block);
|
void UI_block_draw(const struct bContext *C, struct uiBlock *block);
|
||||||
void UI_block_update_from_old(const struct bContext *C, struct uiBlock *block);
|
void UI_block_update_from_old(const struct bContext *C, struct uiBlock *block);
|
||||||
|
|||||||
@@ -367,10 +367,10 @@ static void ui_block_bounds_calc_centered_pie(uiBlock *block)
|
|||||||
|
|
||||||
static void ui_block_bounds_calc_popup(
|
static void ui_block_bounds_calc_popup(
|
||||||
wmWindow *window, uiBlock *block,
|
wmWindow *window, uiBlock *block,
|
||||||
eBlockBoundsCalc bounds_calc, const int xy[2])
|
eBlockBoundsCalc bounds_calc, const int xy[2], int r_xy[2])
|
||||||
{
|
{
|
||||||
int width, height, oldwidth, oldheight;
|
int width, height, oldwidth, oldheight;
|
||||||
int oldbounds, xmax, ymax;
|
int oldbounds, xmax, ymax, raw_x, raw_y;
|
||||||
const int margin = UI_SCREEN_MARGIN;
|
const int margin = UI_SCREEN_MARGIN;
|
||||||
rcti rect, rect_bounds;
|
rcti rect, rect_bounds;
|
||||||
int ofs_dummy[2];
|
int ofs_dummy[2];
|
||||||
@@ -408,8 +408,8 @@ static void ui_block_bounds_calc_popup(
|
|||||||
|
|
||||||
/* offset block based on mouse position, user offset is scaled
|
/* offset block based on mouse position, user offset is scaled
|
||||||
* along in case we resized the block in ui_block_bounds_calc_text */
|
* along in case we resized the block in ui_block_bounds_calc_text */
|
||||||
rect.xmin = xy[0] + block->rect.xmin + (block->mx * width) / oldwidth;
|
raw_x = rect.xmin = xy[0] + block->rect.xmin + (block->mx * width) / oldwidth;
|
||||||
rect.ymin = xy[1] + block->rect.ymin + (block->my * height) / oldheight;
|
raw_y = rect.ymin = xy[1] + block->rect.ymin + (block->my * height) / oldheight;
|
||||||
rect.xmax = rect.xmin + width;
|
rect.xmax = rect.xmin + width;
|
||||||
rect.ymax = rect.ymin + height;
|
rect.ymax = rect.ymin + height;
|
||||||
|
|
||||||
@@ -423,6 +423,13 @@ static void ui_block_bounds_calc_popup(
|
|||||||
|
|
||||||
/* now recompute bounds and safety */
|
/* now recompute bounds and safety */
|
||||||
ui_block_bounds_calc(block);
|
ui_block_bounds_calc(block);
|
||||||
|
|
||||||
|
/* If given, adjust input coordinates such that they would generate real final popup position.
|
||||||
|
* Needed to handle correctly floating panels once they have been dragged around, see T52999. */
|
||||||
|
if (r_xy) {
|
||||||
|
r_xy[0] = xy[0] + block->rect.xmin - raw_x;
|
||||||
|
r_xy[1] = xy[1] + block->rect.ymin - raw_y;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* used for various cases */
|
/* used for various cases */
|
||||||
@@ -1233,7 +1240,7 @@ void UI_block_update_from_old(const bContext *C, uiBlock *block)
|
|||||||
block->oldblock = NULL;
|
block->oldblock = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UI_block_end_ex(const bContext *C, uiBlock *block, const int xy[2])
|
void UI_block_end_ex(const bContext *C, uiBlock *block, const int xy[2], int r_xy[2])
|
||||||
{
|
{
|
||||||
wmWindow *window = CTX_wm_window(C);
|
wmWindow *window = CTX_wm_window(C);
|
||||||
Scene *scene = CTX_data_scene(C);
|
Scene *scene = CTX_data_scene(C);
|
||||||
@@ -1301,7 +1308,7 @@ void UI_block_end_ex(const bContext *C, uiBlock *block, const int xy[2])
|
|||||||
/* fallback */
|
/* fallback */
|
||||||
case UI_BLOCK_BOUNDS_POPUP_MOUSE:
|
case UI_BLOCK_BOUNDS_POPUP_MOUSE:
|
||||||
case UI_BLOCK_BOUNDS_POPUP_MENU:
|
case UI_BLOCK_BOUNDS_POPUP_MENU:
|
||||||
ui_block_bounds_calc_popup(window, block, block->bounds_type, xy);
|
ui_block_bounds_calc_popup(window, block, block->bounds_type, xy, r_xy);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1319,7 +1326,7 @@ void UI_block_end(const bContext *C, uiBlock *block)
|
|||||||
{
|
{
|
||||||
wmWindow *window = CTX_wm_window(C);
|
wmWindow *window = CTX_wm_window(C);
|
||||||
|
|
||||||
UI_block_end_ex(C, block, &window->eventstate->x);
|
UI_block_end_ex(C, block, &window->eventstate->x, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************** BLOCK DRAWING FUNCTION ************* */
|
/* ************** BLOCK DRAWING FUNCTION ************* */
|
||||||
|
|||||||
@@ -1877,8 +1877,9 @@ uiBlock *ui_popup_block_refresh(
|
|||||||
/* defer this until blocks are translated (below) */
|
/* defer this until blocks are translated (below) */
|
||||||
block->oldblock = NULL;
|
block->oldblock = NULL;
|
||||||
|
|
||||||
if (!block->endblock)
|
if (!block->endblock) {
|
||||||
UI_block_end_ex(C, block, handle->popup_create_vars.event_xy);
|
UI_block_end_ex(C, block, handle->popup_create_vars.event_xy, handle->popup_create_vars.event_xy);
|
||||||
|
}
|
||||||
|
|
||||||
/* if this is being created from a button */
|
/* if this is being created from a button */
|
||||||
if (but) {
|
if (but) {
|
||||||
|
|||||||
@@ -565,6 +565,10 @@ PyDoc_STRVAR(bpy_bm_utils_face_split_edgenet_doc,
|
|||||||
" :type edgenet: :class:`bmesh.types.BMEdge`\n"
|
" :type edgenet: :class:`bmesh.types.BMEdge`\n"
|
||||||
" :return: The newly created faces.\n"
|
" :return: The newly created faces.\n"
|
||||||
" :rtype: tuple of (:class:`bmesh.types.BMFace`)\n"
|
" :rtype: tuple of (:class:`bmesh.types.BMFace`)\n"
|
||||||
|
"\n"
|
||||||
|
" .. note::\n"
|
||||||
|
"\n"
|
||||||
|
" Regions defined by edges need to connect to the face, otherwise they're ignored as loose edges.\n"
|
||||||
);
|
);
|
||||||
static PyObject *bpy_bm_utils_face_split_edgenet(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
|
static PyObject *bpy_bm_utils_face_split_edgenet(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user